You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@trafficcontrol.apache.org by GitBox <gi...@apache.org> on 2021/06/02 07:18:40 UTC

[GitHub] [trafficcontrol] dmohan001c opened a new pull request #5905: Add TO Client API for Jobs Automation

dmohan001c opened a new pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905


   ## What does this PR (Pull Request) do?
   
   - [x] This PR is not related to any Issue
   
   ## Which Traffic Control components are affected by this PR?
   
   - CDN in a Box
   - Traffic Control Client <!-- Please specify which; e.g. 'Python', 'Go', 'Java' -->
   - Traffic Ops
   - CI tests
   
   ## What is the best way to verify this PR?
   Execute all the Integration tests and make sure the tests passed.
   
   ## The following criteria are ALL met by this PR
   <!-- Check the boxes to signify that the associated statement is true. To
   "check a box", replace the space inside of the square brackets with an 'x'.
   e.g.
   
   - [ x] <- Wrong
   - [x ] <- Wrong
   - [] <- Wrong
   - [*] <- Wrong
   - [x] <- Correct!
   
   -->
   
   - [x] This PR includes tests OR I have explained why tests are unnecessary
   - [x] This PR includes documentation OR I have explained why documentation is unnecessary
   - [x] This PR includes an update to CHANGELOG.md OR such an update is not necessary
   - [x] This PR includes any and all required license headers
   - [x] This PR **DOES NOT FIX A SERIOUS SECURITY VULNERABILITY** (see [the Apache Software Foundation's security guidelines](https://www.apache.org/security/) for details)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677605846



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""

Review comment:
       Same here.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] zrhoffman merged pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
zrhoffman merged pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677606500



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob

Review comment:
       Same here. This variable should be: `blankAssetUrlJob` oo you can have URL in caps




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677606144



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob

Review comment:
       Same here. This variable should be: `invalidAssetUrlJob`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#issuecomment-887931010


   Code has been correctly refactored to TO client and the coverage is good too.
   Api/v4 and E2E-Integration Tests pass on local.
   A few minor comments. Once fixed, the PR should be good to merge.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r676794920



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -36,6 +36,18 @@ func TestJobs(t *testing.T) {
 		GetTestJobs(t)
 		GetTestInvalidationJobs(t)
 		JobCollisionWarningTest(t)
+		GetTestJobsByValidData(t)
+		GetTestJobsByInvalidData(t)
+		CreateTestJobsInvalidDS(t)
+		CreateTestJobsAlreadyExistTTL(t)
+		CreateTestJobswithPastDate(t)

Review comment:
       nit: change `w` in with to capital letter




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677606500



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob

Review comment:
       Same here. This variable should be: blankAssetUrlJob




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678088691



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob

Review comment:
       updated.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677613961



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob
+	assetURL = ""
+	blankasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected assetUrl: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank created by
+	blankCreatedByJob := realJob
+	createdBy := ""
+	blankCreatedByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankCreatedByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected createdBy: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs created by
+	createdByJob := realJob
+	createdBy = "operator"
+	createdByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(createdByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'createdBy' of existing invalidation jobs!. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank parameters
+	blankParametersJob := realJob
+	parameters := ""
+	blankParametersJob.Parameters = &parameters
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankParametersJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected parameters: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs start date after 2 days
+	startDateFutureJob := realJob
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: must be within two days from now. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with past start date
+	pastStartDateJob := realJob
+	dt = time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format past start date
+	pastStartDateJob = realJob
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format Future start date
+	startDateFutureJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Expected Content invalidation job updated. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusOK {
+		t.Errorf("Expected status code 200, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format Future start date
+	startDateFutureJob = realJob
+	dt = time.Now()
+	dt.Format(".000")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Expected Content invalidation job updated. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusOK {
+		t.Errorf("Expected status code 200, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format Future start date

Review comment:
       nit: Spelling mistake `standartd`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c closed pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c closed pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r675075938



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -36,6 +36,18 @@ func TestJobs(t *testing.T) {
 		GetTestJobs(t)
 		GetTestInvalidationJobs(t)
 		JobCollisionWarningTest(t)
+		GetTestJobsByValidData(t)
+		GetTestJobsByInvalidData(t)
+		CreateTestJobsInvalidds(t)

Review comment:
       Spell check on `Invalids`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 edited a comment on pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 edited a comment on pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#issuecomment-887931010


   Code has been correctly refactored to TO client.
   Api/v4 and E2E-Integration Tests pass on local.
   A few minor comments. Once fixed, the PR should be good to merge.


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r679357997



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {

Review comment:
       From what I understand, empty date implies `time.Time{}`, which resolves to `0001-01-01 00:00:00 +0000 UTC`. In other words that means a date set in past and we already have a test case for the past start date. So, no other change required.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678096529



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {

Review comment:
       accidently, it was missed. I added the status code check.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678096737



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob
+	assetURL = ""
+	blankasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected assetUrl: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank created by
+	blankCreatedByJob := realJob
+	createdBy := ""
+	blankCreatedByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankCreatedByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected createdBy: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs created by
+	createdByJob := realJob
+	createdBy = "operator"
+	createdByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(createdByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'createdBy' of existing invalidation jobs!. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank parameters
+	blankParametersJob := realJob
+	parameters := ""
+	blankParametersJob.Parameters = &parameters
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankParametersJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected parameters: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs start date after 2 days
+	startDateFutureJob := realJob
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: must be within two days from now. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with past start date
+	pastStartDateJob := realJob
+	dt = time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format past start date
+	pastStartDateJob = realJob
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format Future start date
+	startDateFutureJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Expected Content invalidation job updated. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusOK {
+		t.Errorf("Expected status code 200, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format Future start date
+	startDateFutureJob = realJob
+	dt = time.Now()
+	dt.Format(".000")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Expected Content invalidation job updated. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusOK {
+		t.Errorf("Expected status code 200, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format Future start date

Review comment:
       updated




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r675779465



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       Umm.. is the expectation to create the job request? or not to, since the job already exists?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677603556



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob
+	assetURL = ""
+	blankasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected assetUrl: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank created by
+	blankCreatedByJob := realJob
+	createdBy := ""
+	blankCreatedByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankCreatedByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected createdBy: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs created by
+	createdByJob := realJob
+	createdBy = "operator"
+	createdByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(createdByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'createdBy' of existing invalidation jobs!. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank parameters
+	blankParametersJob := realJob
+	parameters := ""
+	blankParametersJob.Parameters = &parameters
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankParametersJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected parameters: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs start date after 2 days
+	startDateFutureJob := realJob
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: must be within two days from now. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with past start date
+	pastStartDateJob := realJob
+	dt = time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format past start date
+	pastStartDateJob = realJob
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format past start date

Review comment:
       nit: Spelling mistake `standartd`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678087057



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob

Review comment:
       updated.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677605082



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob

Review comment:
       Same here. This variable should be: `blankDsIdJob`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678087694



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob

Review comment:
       Fixed

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""

Review comment:
       updated.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob

Review comment:
       updated.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677604552



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob

Review comment:
       Since we are following camelcase, this variable should be: `invalidDsIdJob`




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c closed pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c closed pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677107246



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -36,6 +36,18 @@ func TestJobs(t *testing.T) {
 		GetTestJobs(t)
 		GetTestInvalidationJobs(t)
 		JobCollisionWarningTest(t)
+		GetTestJobsByValidData(t)
+		GetTestJobsByInvalidData(t)
+		CreateTestJobsInvalidDS(t)
+		CreateTestJobsAlreadyExistTTL(t)
+		CreateTestJobswithPastDate(t)

Review comment:
       Fixed.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678047093



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       yes, we have a test case to create with this scenario. If it's not the expected scenario, I will deprecate this test.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678237132



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {

Review comment:
       I am not able to pass invalid Date to the date field. By default, it throws an error in the IDE. I feel there is no need to imply this validation

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {

Review comment:
       Kindly provide your comments on the same.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob
+	assetURL = ""
+	blankasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected assetUrl: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank created by
+	blankCreatedByJob := realJob
+	createdBy := ""
+	blankCreatedByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankCreatedByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected createdBy: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs created by
+	createdByJob := realJob
+	createdBy = "operator"
+	createdByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(createdByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'createdBy' of existing invalidation jobs!. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank parameters
+	blankParametersJob := realJob
+	parameters := ""
+	blankParametersJob.Parameters = &parameters
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankParametersJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected parameters: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs start date after 2 days
+	startDateFutureJob := realJob
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: must be within two days from now. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with past start date
+	pastStartDateJob := realJob
+	dt = time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format past start date
+	pastStartDateJob = realJob
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format past start date

Review comment:
       updated.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob

Review comment:
       updated.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob

Review comment:
       updated.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""

Review comment:
       updated.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob

Review comment:
       Fixed




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678086557



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob
+	assetURL = ""
+	blankasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected assetUrl: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank created by
+	blankCreatedByJob := realJob
+	createdBy := ""
+	blankCreatedByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankCreatedByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected createdBy: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs created by
+	createdByJob := realJob
+	createdBy = "operator"
+	createdByJob.CreatedBy = &createdBy
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(createdByJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'createdBy' of existing invalidation jobs!. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank parameters
+	blankParametersJob := realJob
+	parameters := ""
+	blankParametersJob.Parameters = &parameters
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankParametersJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected parameters: cannot be blank. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs start date after 2 days
+	startDateFutureJob := realJob
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	startDateFutureJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(startDateFutureJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: must be within two days from now. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with past start date
+	pastStartDateJob := realJob
+	dt = time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -3),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with RFC Format past start date
+	pastStartDateJob = realJob
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with UNIX Format past start date
+	pastStartDateJob = realJob
+	pastStartDateJob.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(pastStartDateJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected startTime: cannot be in the past. alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update jobs with non standartd Format past start date

Review comment:
       updated




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r676505498



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -36,6 +36,18 @@ func TestJobs(t *testing.T) {
 		GetTestJobs(t)
 		GetTestInvalidationJobs(t)
 		JobCollisionWarningTest(t)
+		GetTestJobsByValidData(t)
+		GetTestJobsByInvalidData(t)
+		CreateTestJobsInvalidds(t)

Review comment:
       updated.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677574583



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       So, we are ok to create duplicate jobs for a same DS with exact start and TTL times?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677617640



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {

Review comment:
       All update cases have been covered but I see one missing: https://github.comcast.com/cdn/cdn-tests/blob/master/trafficops/tests/jobs_test.go#L176 or did I misconstrues? 




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677610998



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {

Review comment:
       You normally check the status code response `if reqInf.StatusCode`, but this is the only function that doesn't have that check. Was there a reason for this difference?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r676531040



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       yes, this is the expected error message.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r678353479



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       No need to deprecate. I was merely trying to understand why would we create two jobs with same start and TTL times belonging to one DS.

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidds(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)

Review comment:
       No need to deprecate. I was merely trying to understand why would we create duplicate jobs with same start and TTL times belonging to one DS.




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r677606500



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob
+	assetURL := "http://google.com"
+	invalidasseturlJob.AssetURL = &assetURL
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invalidasseturlJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot set asset URL that does not start with Delivery Service origin URL: http://origin.infra.ciab.test. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank asset url
+	blankasseturlJob := realJob

Review comment:
       Same here. This variable should be: `blankAssetUrlJob` or you can have URL in caps

##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -360,3 +372,843 @@ func GetTestInvalidationJobs(t *testing.T) {
 		}
 	}
 }
+
+func GetTestJobsByValidData(t *testing.T) {
+	toJobs, _, err := TOSession.GetInvalidationJobs(client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("error getting jobs %v - alerts: %+v", err, toJobs.Alerts)
+	}
+	if len(toJobs.Response) < 1 {
+		t.Fatal("Need at least one Jobs to test GET Jobs scenario")
+	}
+	jobs := toJobs.Response[0]
+
+	assetUrl := jobs.AssetURL
+	createdBy := jobs.CreatedBy
+	id := jobs.ID
+	dsName := jobs.DeliveryService
+	keyword := jobs.Keyword
+
+	//Get Jobs by Asset URL
+	if len(*assetUrl) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("assetUrl", *assetUrl)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by Asset URL, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Asset URL Field is Empty, so can't test get jobs")
+	}
+
+	//Get Jobs by CreatedBy
+	if len(*createdBy) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("createdBy", *createdBy)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by CreatedBy, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("CreatedBy Field is empty, so can't test get jobs")
+	}
+
+	//Get Jobs by ID
+	if *id > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("id", strconv.FormatUint(uint64(*id), 10))
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) != 1 {
+			t.Errorf("Expected only one Jobs response for GET Jobs by ID, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("ID Field is empty, so can't test get jobs %d", *id)
+	}
+
+	//Get Jobs by Keyword
+	if len(*keyword) > 1 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("Keyword", *keyword)
+		toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+		if len(toJobs.Response) < 1 {
+			t.Errorf("Expected atleast one Jobs response for GET Jobs by keyword, but found %d ", len(toJobs.Response))
+		}
+	} else {
+		t.Errorf("Keyword field is empty, so can't test get jobs")
+	}
+
+	//Get Delivery Service ID by Name
+	if len(*dsName) > 0 {
+		opts := client.NewRequestOptions()
+		opts.QueryParameters.Set("xmlId", *dsName)
+		toDSes, _, _ := TOSession.GetDeliveryServices(opts)
+		if len(toDSes.Response) > 0 {
+			dsId := toDSes.Response[0].ID
+			if *dsId > 0 {
+				//Get Jobs by DSID
+				opts := client.NewRequestOptions()
+				opts.QueryParameters.Set("dsId", strconv.Itoa(*dsId))
+				toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+				if len(toJobs.Response) < 1 {
+					t.Errorf("Expected atleast one Jobs response for GET Jobs by delivery service, but found %d ", len(toJobs.Response))
+				}
+			} else {
+				t.Error("Delivery service id is empty")
+			}
+		} else {
+			t.Error("No responses for get delivery service by name")
+		}
+	} else {
+		t.Error("Delivery Service Name field is empty, so can't retrive ID from name")
+	}
+
+	//Get UserID ID by Username
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("username", "admin")
+	userResp, _, _ := TOSession.GetUsers(opts)
+	if len(userResp.Response) > 0 {
+		userId := userResp.Response[0].ID
+		if *userId > 0 {
+			//Get Jobs by userID
+			opts := client.NewRequestOptions()
+			opts.QueryParameters.Set("userId", strconv.Itoa(*userId))
+			toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+			if len(toJobs.Response) < 1 {
+				t.Errorf("Expected atleast one Jobs response for GET Jobs by users, but found %d ", len(toJobs.Response))
+			}
+		} else {
+			t.Error("User id is empty")
+		}
+	} else {
+		t.Error("No user response available for get user by name")
+	}
+}
+
+func GetTestJobsByInvalidData(t *testing.T) {
+
+	//Get Jobs by Invalid Asset URL
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("assetUrl", "abcd")
+	toJobs, _, _ := TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Asset URL, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid CreatedBy
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("createdBy", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid CreatedBy, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid ID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("id", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid ID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid Keyword
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("keyword", "invalid")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid Keyword, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("dsId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSID, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid DSName
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", "abcd")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid DSName, but found %d ", len(toJobs.Response))
+	}
+
+	//Get Jobs by Invalid userID
+	opts = client.NewRequestOptions()
+	opts.QueryParameters.Set("userId", "11111")
+	toJobs, _, _ = TOSession.GetInvalidationJobs(opts)
+	if len(toJobs.Response) != 0 {
+		t.Errorf("Expected no response from Get Jobs by Invalid userID, but found %d ", len(toJobs.Response))
+	}
+}
+
+func CreateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to test invalid ds")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	//Invalid DS
+	request := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr("invalid"),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected No DeliveryService exists matching identifier: %v - alerts: %v", request.DeliveryService, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Missing DS
+	request = tc.InvalidationJobInput{
+		Regex:     job.Regex,
+		StartTime: job.StartTime,
+		TTL:       job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty DS
+	request = tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(""),
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected deliveryService: cannot be blank., No DeliveryService exists matching identifier: - alerts: %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsAlreadyExistTTL(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Error("Need at least one Invalidation Jobs to create duplicate data")
+	}
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Now().Add(time.Minute).UTC(),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateTestJobsWithPastDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//past start date
+	dt := time.Now()
+	dt.Format("2019-06-18 21:28:31")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//RFC Format past start date
+	dt = time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Non standard Format past start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, -5),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//unix standard format past start date
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  time.Unix(1, 0),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: must be in the future - Alert %v", resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateTestJobsWithFutureDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//RFC Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//Non standard format Future start date
+	dt = time.Now()
+	dt.Format("2020-03-11 14:12:20-06")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+
+	//UNIX format Future start date
+	dt = time.Now()
+	dt.Format(".000")
+	job = testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+		TTL:             job.TTL,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err != nil {
+		t.Errorf("Expected Invalidation request created, but found error %v - Alert %v", err, resp.Alerts)
+	}
+}
+
+func CreateJobsMissingDate(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing date
+	job := testData.InvalidationJobs[0]
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected startTime: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingRegex(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing Regex
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty Regex
+	job.Regex = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected regex: cannot be blank, but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func CreateJobsMissingTtl(t *testing.T) {
+	if len(testData.InvalidationJobs) < 1 {
+		t.Fatal("Need at least one Invalidation Job to test creating an invalid Job")
+	}
+	//Missing TTL
+	//Future start date
+	dt := time.Now()
+	dt.Format("2019-10-12T07:20:50.52Z")
+	job := testData.InvalidationJobs[0]
+	job.StartTime = &tc.Time{
+		Time:  dt.AddDate(0, 0, 1),
+		Valid: true,
+	}
+	testData.InvalidationJobs[0] = job
+	request := tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		StartTime:       job.StartTime,
+	}
+	resp, reqInf, err := TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//Empty TTL
+	job.TTL = nil
+	request = tc.InvalidationJobInput{
+		DeliveryService: job.DeliveryService,
+		Regex:           job.Regex,
+		TTL:             job.TTL,
+		StartTime:       job.StartTime,
+	}
+	resp, _, err = TOSession.CreateInvalidationJob(request, client.RequestOptions{})
+	if err == nil {
+		t.Errorf("Expected ttl: cannot be blank., ttl: must be a number of hours, or a duration string e.g. '48h', but no error found %v - Alert %v", resp, resp.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+}
+
+func UpdateTestJobsInvalidDS(t *testing.T) {
+	if len(testData.DeliveryServices) < 2 {
+		t.Fatal("Need at least two Delivery Service to update Invalidation Job")
+	}
+	if testData.DeliveryServices[0].XMLID == nil || testData.DeliveryServices[1].XMLID == nil {
+		t.Fatal("Found a Delivery Service in the testing data with null or undefined XMLID")
+	}
+	xmlID := *testData.DeliveryServices[0].XMLID
+	startTime := tc.Time{
+		Time:  time.Now().Add(time.Hour),
+		Valid: true,
+	}
+	firstJob := tc.InvalidationJobInput{
+		DeliveryService: util.InterfacePtr(&xmlID),
+		Regex:           util.StrPtr(`/\.*([A-Z]0?)`),
+		TTL:             util.InterfacePtr(16),
+		StartTime:       &startTime,
+	}
+
+	resp, _, err := TOSession.CreateInvalidationJob(firstJob, client.RequestOptions{})
+	if err != nil {
+		t.Fatalf("Unexpected error creating a content invalidation Job: %v - alerts: %+v", err, resp.Alerts)
+	}
+	opts := client.NewRequestOptions()
+	opts.QueryParameters.Set("deliveryService", xmlID)
+	jobs, _, err := TOSession.GetInvalidationJobs(opts)
+	if err != nil {
+		t.Fatalf("unable to get invalidation jobs: %v - alerts: %+v", err, jobs.Alerts)
+	}
+
+	var realJob tc.InvalidationJob
+	for i, job := range jobs.Response {
+		if job.StartTime == nil || job.DeliveryService == nil || job.CreatedBy == nil {
+			t.Error("Traffic Ops returned a representation of a content invalidation Job that had null or undefined Start Time and/or Delivery Service and/or Created By")
+			continue
+		}
+		diff := firstJob.StartTime.Time.Sub(job.StartTime.Time)
+		if *job.DeliveryService == xmlID && *job.CreatedBy == "admin" && diff < time.Second {
+			realJob = jobs.Response[i]
+			break
+		}
+	}
+	if realJob.ID == nil || *realJob.ID == 0 {
+		t.Fatal("could not find new job")
+	}
+
+	//update existing jobs with new ds id
+	originalJob := realJob
+	newTime := tc.Time{
+		Time:  startTime.Time.Add(time.Hour * 2),
+		Valid: true,
+	}
+	originalJob.StartTime = &newTime
+	originalJob.DeliveryService = testData.DeliveryServices[1].XMLID
+	alerts, reqInf, err := TOSession.UpdateInvalidationJob(originalJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with invalid ds id
+	invaliddsidJob := realJob
+	invaliddsid := "abcd"
+	invaliddsidJob.DeliveryService = &invaliddsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(invaliddsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected Cannot change 'deliveryService' of existing invalidation job! - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusConflict {
+		t.Errorf("Expected status code 409, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with blank ds id
+	blankdsidJob := realJob
+	blankdsid := ""
+	blankdsidJob.DeliveryService = &blankdsid
+	alerts, reqInf, err = TOSession.UpdateInvalidationJob(blankdsidJob, client.RequestOptions{})
+	if err == nil {
+		t.Fatalf("Expected deliveryService: cannot be blank. - alerts: %+v", alerts.Alerts)
+	}
+	if reqInf.StatusCode != http.StatusBadRequest {
+		t.Errorf("Expected status code 400, got %v", reqInf.StatusCode)
+	}
+
+	//update existing jobs with asset url not starts with origin.infra
+	invalidasseturlJob := realJob

Review comment:
       Same here. This variable should be: `invalidAssetUrlJob` or you can have URL in caps




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] dmohan001c closed pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
dmohan001c closed pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905


   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org



[GitHub] [trafficcontrol] rimashah25 commented on a change in pull request #5905: Add TO Client API for Jobs Automation

Posted by GitBox <gi...@apache.org>.
rimashah25 commented on a change in pull request #5905:
URL: https://github.com/apache/trafficcontrol/pull/5905#discussion_r675777633



##########
File path: traffic_ops/testing/api/v4/jobs_test.go
##########
@@ -36,6 +36,18 @@ func TestJobs(t *testing.T) {
 		GetTestJobs(t)
 		GetTestInvalidationJobs(t)
 		JobCollisionWarningTest(t)
+		GetTestJobsByValidData(t)
+		GetTestJobsByInvalidData(t)
+		CreateTestJobsInvalidds(t)

Review comment:
       nit: can you capitalize `ds` (Delivery Service) in the function, makes it easy to read?




-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: issues-unsubscribe@trafficcontrol.apache.org

For queries about this service, please contact Infrastructure at:
users@infra.apache.org