Example #1
0
func TestCreateNewJob(t *testing.T) {
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Testing data
	tests := []struct {
		givenURI    string
		givenBody   string
		givenJobs   map[string]*job.Job
		wantCode    int
		wantBody    string
		wantJobslen int
	}{
		{
			givenURI:    "/api/v1/jobs",
			givenBody:   `{"active": true, "description": "Simple hello world", "url": "http://crons.test.com/hello-world", "when": "@daily", "name": "hello-world"}`,
			givenJobs:   make(map[string]*job.Job),
			wantCode:    http.StatusCreated,
			wantJobslen: 1,
		},

		{
			givenURI:    "/api/v1/jobs",
			givenBody:   `{"active": true, "description": "Simple hello world", "url": "http://crons.test.com/hello-world", "when": "@daily"}`,
			givenJobs:   make(map[string]*job.Job),
			wantCode:    http.StatusBadRequest,
			wantJobslen: 0,
		},
	}

	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Jobs = test.givenJobs
		testStorageClient.JobCounter = len(test.givenJobs)

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		b := bytes.NewReader([]byte(test.givenBody))
		r, _ := http.NewRequest("POST", test.givenURI, b)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)

		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}
		if len(testStorageClient.Jobs) != test.wantJobslen {
			t.Errorf("Expected len '%d'. Got '%d' instead ", len(testStorageClient.Jobs), test.wantJobslen)
		}
	}
}
Example #2
0
func TestPing(t *testing.T) {
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Testing data
	tests := []struct {
		givenURI string
		wantCode int
		wantBody interface{}
	}{
		{
			givenURI: "/api/v1/ping",
			wantCode: http.StatusOK,
			wantBody: "\"pong\"\n",
		},
	}

	// Tests
	for _, test := range tests {

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}

		got, _ := ioutil.ReadAll(w.Body)
		if string(got) != test.wantBody {
			t.Errorf("Expected body '%s'. Got '%s' instead ", test.wantBody, string(got))
		}
	}

}
Example #3
0
func TestGetMostPopular(t *testing.T) {
	tests := []struct {
		givenURI    string
		givenClient *nyttest.Client

		wantCode int
		wantBody interface{}
	}{
		{
			"/svc/nyt/most-popular/my-resource/my-section/1",
			&nyttest.Client{
				TestGetMostPopular: func(resourceType, section string, timeframe uint) ([]*nyt.MostPopularResult, error) {
					if resourceType != "my-resource" {
						t.Errorf("expected resourceType of 'my-resource'; got %#v", resourceType)
					}
					if section != "my-section" {
						t.Errorf("expected section of 'my-section'; got %#v", section)
					}
					if timeframe != uint(1) {
						t.Errorf("expected timeframe of '1'; got %#v", timeframe)
					}
					return []*nyt.MostPopularResult{
						&nyt.MostPopularResult{
							Url: "https://www.nytimes.com/awesome-article",
							Id:  uint64(12345),
						},
					}, nil
				},
			},

			http.StatusOK,
			[]interface{}{
				map[string]interface{}{
					"id":  float64(12345),
					"url": "https://www.nytimes.com/awesome-article",
				},
			},
		},
		{
			"/svc/nyt/most-popular/my-resource/my-section/10",
			&nyttest.Client{
				TestGetMostPopular: func(resourceType, section string, timeframe uint) ([]*nyt.MostPopularResult, error) {
					if resourceType != "my-resource" {
						t.Errorf("expected resourceType of 'my-resource'; got %#v", resourceType)
					}
					if section != "my-section" {
						t.Errorf("expected section of 'my-section'; got %#v", section)
					}
					if timeframe != uint(10) {
						t.Errorf("expected timeframe of '10'; got %#v", timeframe)
					}
					return nil, errors.New("unacceptable!!!")
				},
			},

			http.StatusInternalServerError,
			map[string]interface{}{
				"error": "unacceptable!!!",
			},
		},
	}

	for _, test := range tests {

		srvr := server.NewSimpleServer(nil)
		srvr.Register(&SimpleService{client: test.givenClient})

		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		srvr.ServeHTTP(w, r)

		if w.Code != test.wantCode {
			t.Errorf("expected response code of %d; got %d", test.wantCode, w.Code)
		}

		var got interface{}
		err := json.NewDecoder(w.Body).Decode(&got)
		if err != nil {
			t.Error("unable to JSON decode response body: ", err)
		}

		if !reflect.DeepEqual(got, test.wantBody) {
			t.Errorf("expected response body of\n%#v;\ngot\n%#v", test.wantBody, got)
		}
	}

}
Example #4
0
func TestGetCats(t *testing.T) {
	tests := []struct {
		givenURI    string
		givenClient *nyttest.Client

		wantCode int
		wantBody interface{}
	}{
		{
			"/svc/nyt/cats",
			&nyttest.Client{
				TestSemanticConceptSearch: func(conceptType, concept string) ([]*nyt.SemanticConceptArticle, error) {
					return []*nyt.SemanticConceptArticle{
						&nyt.SemanticConceptArticle{
							Url: "https://www.nytimes.com/awesome-article",
						},
					}, nil
				},
			},

			http.StatusOK,
			[]interface{}{
				map[string]interface{}{
					"url": "https://www.nytimes.com/awesome-article",
				},
			},
		},
		{
			"/svc/nyt/cats",
			&nyttest.Client{
				TestSemanticConceptSearch: func(conceptType, concept string) ([]*nyt.SemanticConceptArticle, error) {
					return nil, errors.New("NOPE!")
				},
			},

			http.StatusServiceUnavailable,
			map[string]interface{}{
				"error": "sorry, this service is unavailable",
			},
		},
	}

	for _, test := range tests {

		srvr := server.NewSimpleServer(nil)
		srvr.Register(&JSONService{client: test.givenClient})

		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		srvr.ServeHTTP(w, r)

		if w.Code != test.wantCode {
			t.Errorf("expected response code of %d; got %d", test.wantCode, w.Code)
		}

		var got interface{}
		err := json.NewDecoder(w.Body).Decode(&got)
		if err != nil {
			t.Error("unable to JSON decode response body: ", err)
		}

		if !reflect.DeepEqual(got, test.wantBody) {
			t.Errorf("expected response body of\n%#v;\ngot\n%#v", test.wantBody, got)
		}

		// ** THIS IS REQUIRED in order to run the test multiple times.
		metrics.DefaultRegistry.UnregisterAll()
	}

}
Example #5
0
func TestGetJobs(t *testing.T) {
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Testing data
	tests := []struct {
		givenURI       string
		givenJobs      map[string]*job.Job
		wantCode       int
		wantBodyLength int
	}{
		{
			givenURI:       "/api/v1/jobs",
			givenJobs:      make(map[string]*job.Job),
			wantCode:       http.StatusOK,
			wantBodyLength: 0,
		},
		{
			givenURI: "/api/v1/jobs",
			givenJobs: map[string]*job.Job{
				"job:1": &job.Job{ID: 1, Name: "test1", Description: "test1", When: "@daily", Active: true, URL: &url.URL{}},
				"job:2": &job.Job{ID: 2, Name: "test2", Description: "test2", When: "0 30 * * * *", Active: true, URL: &url.URL{}},
			},
			wantCode:       http.StatusOK,
			wantBodyLength: 2,
		},
	}

	// Tests
	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Jobs = test.givenJobs
		testStorageClient.JobCounter = len(test.givenJobs)

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}

		var got []*job.Job
		err := json.NewDecoder(w.Body).Decode(&got)
		if err != nil {
			t.Error(err)
		}

		if len(got) != test.wantBodyLength {
			t.Errorf("Expected length '%d'. Got '%d' instead ", test.wantBodyLength, len(got))
		}
	}
}
Example #6
0
func TestGetResultsPaginated(t *testing.T) {
	results := map[string]map[string]*job.Result{
		"job:1:results": map[string]*job.Result{},
	}
	totalResults := 54
	pageSize := 7
	testStorageClient := storage.NewDummy()
	// Custom pagination
	paginationTestConfig := config.NewAppConfig(os.Getenv(config.KhronosConfigFileKey))
	paginationTestConfig.APIResourcesPerPage = pageSize
	testCronEngine := schedule.NewDummyCron(paginationTestConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Create our custom dummy results database
	j := &job.Job{ID: 1, Name: "test1", When: "@daily", Active: true, URL: &url.URL{}}
	for i := 1; i <= totalResults; i++ {
		v := &job.Result{ID: i, Job: j, Out: fmt.Sprintf("test%d", i), Status: job.ResultInternalError, Start: time.Now().UTC(), Finish: time.Now().UTC()}
		k := fmt.Sprintf("result:%d", i)
		results["job:1:results"][k] = v
	}

	// Testing data
	tests := []struct {
		givenURI      string
		wantResultIDs []int
	}{
		{
			givenURI:      "/api/v1/jobs/1/results",
			wantResultIDs: []int{1, 2, 3, 4, 5, 6, 7},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=0",
			wantResultIDs: []int{1, 2, 3, 4, 5, 6, 7},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=1",
			wantResultIDs: []int{1, 2, 3, 4, 5, 6, 7},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=2",
			wantResultIDs: []int{8, 9, 10, 11, 12, 13, 14},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=3",
			wantResultIDs: []int{15, 16, 17, 18, 19, 20, 21},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=4",
			wantResultIDs: []int{22, 23, 24, 25, 26, 27, 28},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=5",
			wantResultIDs: []int{29, 30, 31, 32, 33, 34, 35},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=6",
			wantResultIDs: []int{36, 37, 38, 39, 40, 41, 42},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=7",
			wantResultIDs: []int{43, 44, 45, 46, 47, 48, 49},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=8",
			wantResultIDs: []int{50, 51, 52, 53, 54},
		},
		{
			givenURI:      "/api/v1/jobs/1/results?page=9",
			wantResultIDs: []int{},
		},
	}

	// Tests
	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Results = results
		testStorageClient.Jobs = map[string]*job.Job{"job:1": j}

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  paginationTestConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)

		var got []*job.Result
		err := json.NewDecoder(w.Body).Decode(&got)
		if err != nil {
			t.Error(err)
		}

		// Check length
		if len(got) != len(test.wantResultIDs) {
			t.Errorf("Expected length '%d'. Got '%d' instead ", len(test.wantResultIDs), len(got))
		}

		// Check IDs ok (should be in order)
		for k, i := range test.wantResultIDs {
			if got[k].ID != i {
				t.Errorf("Expected result id '%d'. Got '%d' instead ", i, got[k].ID)
			}
		}
	}
}
Example #7
0
func TestDeleteResult(t *testing.T) {
	j := &job.Job{ID: 1, Name: "test1", Description: "test1", When: "@daily", Active: true, URL: &url.URL{}}
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Testing data
	tests := []struct {
		givenURI          string
		givenResults      map[string]map[string]*job.Result
		givenJobs         map[string]*job.Job
		wantCode          int
		wantDeletedResult string
	}{
		{
			givenURI:     "/api/v1/jobs/1/results/1",
			givenResults: make(map[string]map[string]*job.Result),
			givenJobs:    make(map[string]*job.Job),
			wantCode:     http.StatusInternalServerError,
		},
		{
			givenURI:     "/api/v1/jobs/1/results/1",
			givenResults: make(map[string]map[string]*job.Result),
			givenJobs:    map[string]*job.Job{"job:1": j},
			wantCode:     http.StatusNoContent,
		},
		{
			givenURI: "/api/v1/jobs/1/results/1",
			givenResults: map[string]map[string]*job.Result{
				"job:1:results": map[string]*job.Result{
					"result:1": &job.Result{ID: 1, Job: j, Out: "test1", Status: job.ResultOK, Start: time.Now().UTC(), Finish: time.Now().UTC()},
				},
			},
			givenJobs:         map[string]*job.Job{"job:1": j},
			wantCode:          http.StatusNoContent,
			wantDeletedResult: "result:1",
		},
	}

	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Results = test.givenResults
		testStorageClient.Jobs = test.givenJobs

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("DELETE", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}

		rs, _ := testStorageClient.Results["job:1:results"]
		if _, ok := rs[test.wantDeletedResult]; ok {
			t.Error("Result should be deleted; present on database")
		}
	}
}
Example #8
0
func TestGetResult(t *testing.T) {
	j := &job.Job{ID: 1, Name: "test1", Description: "test1", When: "@daily", Active: true, URL: &url.URL{}}
	res3 := &job.Result{ID: 3, Job: nil, Out: "test1", Status: job.ResultInternalError, Start: time.Now().UTC(), Finish: time.Now().UTC()}
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Testing data
	tests := []struct {
		givenURI     string
		givenResults map[string]map[string]*job.Result
		givenJobs    map[string]*job.Job
		wantCode     int
		wantResult   *job.Result
	}{
		{
			givenURI:     "/api/v1/jobs/1/results/1",
			givenResults: make(map[string]map[string]*job.Result),
			givenJobs:    make(map[string]*job.Job),
			wantCode:     http.StatusInternalServerError,
		},
		{
			givenURI:     "/api/v1/jobs/1/results/1",
			givenResults: make(map[string]map[string]*job.Result),
			givenJobs:    map[string]*job.Job{"job:1": j},
			wantCode:     http.StatusInternalServerError,
		},
		{
			givenURI: "/api/v1/jobs/1/results/3",
			givenResults: map[string]map[string]*job.Result{
				"job:1:results": map[string]*job.Result{
					"result:1": &job.Result{ID: 1, Job: j, Out: "test1", Status: job.ResultOK, Start: time.Now().UTC(), Finish: time.Now().UTC()},
					"result:2": &job.Result{ID: 2, Job: j, Out: "test1", Status: job.ResultError, Start: time.Now().UTC(), Finish: time.Now().UTC()},
					"result:3": res3, // the one to check
				},
			},
			givenJobs:  map[string]*job.Job{"job:1": j},
			wantCode:   http.StatusOK,
			wantResult: res3,
		},
	}

	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Results = test.givenResults
		testStorageClient.Jobs = test.givenJobs

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}

		// Only check in good results
		if w.Code == http.StatusOK {
			b, err := ioutil.ReadAll(w.Body)

			if err != nil {
				t.Errorf("Error reading result body: %v", err)
			}
			var gotRes *job.Result
			if err := json.Unmarshal(b, &gotRes); err != nil {
				t.Errorf("Error unmarshaling: %v", err)
			}
			// Fix jobs for the deep equal
			gotRes.Job = nil

			if !reflect.DeepEqual(gotRes, test.wantResult) {
				t.Errorf("Expected Result '%#v'. Got '%#v' instead ", test.wantResult, gotRes)
			}
		}

	}
}
Example #9
0
func TestGetJob(t *testing.T) {
	testStorageClient := storage.NewDummy()
	testCronEngine := schedule.NewDummyCron(testConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	j2 := &job.Job{ID: 2, Name: "test2", Description: "test2", When: "0 30 * * * *", Active: false, URL: &url.URL{}}
	// Testing data
	tests := []struct {
		givenURI  string
		givenJobs map[string]*job.Job
		wantCode  int
		wantJob   *job.Job
	}{
		{
			givenURI:  "/api/v1/jobs/1",
			givenJobs: make(map[string]*job.Job),
			wantCode:  http.StatusInternalServerError,
		},
		{
			givenURI: "/api/v1/jobs/2",
			givenJobs: map[string]*job.Job{
				"job:1": &job.Job{ID: 1, Name: "test1", Description: "test1", When: "@daily", Active: true, URL: &url.URL{}},
				"job:2": j2, // The one to check,
				"job:3": &job.Job{ID: 3, Name: "test3", Description: "test3", When: "*/10 30 * 4 * 1", Active: true, URL: &url.URL{}},
			},
			wantCode: http.StatusOK,
			wantJob:  j2,
		},
	}

	// Tests
	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Jobs = test.givenJobs
		testStorageClient.JobCounter = len(test.givenJobs)

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  testConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)
		if w.Code != test.wantCode {
			t.Errorf("Expected response code '%d'. Got '%d' instead ", test.wantCode, w.Code)
		}

		// Only check when ok
		if w.Code == http.StatusOK {
			var got *job.Job
			err := json.NewDecoder(w.Body).Decode(&got)
			if err != nil {
				t.Error(err)
			}

			if !reflect.DeepEqual(got, test.wantJob) {
				t.Errorf("Expected job '%#v'. Got '%#v' instead ", test.wantJob, got)
			}
		}
	}
}
Example #10
0
func TestGetJobsPaginated(t *testing.T) {
	jobs := make(map[string]*job.Job)
	totalJobs := 27
	pageSize := 5
	testStorageClient := storage.NewDummy()
	// Custom pagination
	paginationTestConfig := config.NewAppConfig(os.Getenv(config.KhronosConfigFileKey))
	paginationTestConfig.APIResourcesPerPage = pageSize
	testCronEngine := schedule.NewDummyCron(paginationTestConfig, testStorageClient, 0, "OK")
	testCronEngine.Start(nil)

	// Create our custom dummy job database
	for i := 1; i <= totalJobs; i++ {
		k := fmt.Sprintf("job:%d", i)
		v := &job.Job{ID: i, Name: fmt.Sprintf("test%d", i), When: "@daily", URL: &url.URL{}}
		jobs[k] = v
	}

	// Testing data
	tests := []struct {
		givenURI   string
		wantJobIDs []int
	}{
		{
			givenURI:   "/api/v1/jobs",
			wantJobIDs: []int{1, 2, 3, 4, 5},
		},
		{
			givenURI:   "/api/v1/jobs?page=0",
			wantJobIDs: []int{1, 2, 3, 4, 5},
		},
		{
			givenURI:   "/api/v1/jobs?page=1",
			wantJobIDs: []int{1, 2, 3, 4, 5},
		},
		{
			givenURI:   "/api/v1/jobs?page=2",
			wantJobIDs: []int{6, 7, 8, 9, 10},
		},
		{
			givenURI:   "/api/v1/jobs?page=3",
			wantJobIDs: []int{11, 12, 13, 14, 15},
		},
		{
			givenURI:   "/api/v1/jobs?page=4",
			wantJobIDs: []int{16, 17, 18, 19, 20},
		},
		{
			givenURI:   "/api/v1/jobs?page=5",
			wantJobIDs: []int{21, 22, 23, 24, 25},
		},
		{
			givenURI:   "/api/v1/jobs?page=6",
			wantJobIDs: []int{26, 27},
		},
		{
			givenURI:   "/api/v1/jobs?page=7",
			wantJobIDs: []int{},
		},
	}

	// Tests
	for _, test := range tests {
		// Set our dummy 'database' on the storage client
		testStorageClient.Jobs = jobs
		testStorageClient.JobCounter = totalJobs

		// Create a testing server
		testServer := server.NewSimpleServer(nil)

		// Register our service on the server (we don't need configuration for this service)
		testServer.Register(&KhronosService{
			Config:  paginationTestConfig,
			Storage: testStorageClient,
			Cron:    testCronEngine,
		})

		// Create request and a test recorder
		r, _ := http.NewRequest("GET", test.givenURI, nil)
		w := httptest.NewRecorder()
		testServer.ServeHTTP(w, r)

		var got []*job.Job
		err := json.NewDecoder(w.Body).Decode(&got)
		if err != nil {
			t.Error(err)
		}

		// Check length
		if len(got) != len(test.wantJobIDs) {
			t.Errorf("Expected length '%d'. Got '%d' instead ", len(test.wantJobIDs), len(got))
		}

		// Check IDs ok (should be in order)
		for k, i := range test.wantJobIDs {
			if got[k].ID != i {
				t.Errorf("Expected job id '%d'. Got '%d' instead ", i, got[k].ID)
			}
		}
	}
}
Example #11
0
func TestGet(t *testing.T) {
	testDate := time.Date(2015, 1, 1, 12, 0, 0, 0, time.UTC)

	tests := []struct {
		givenID   string
		givenRepo func(uint64) ([]*SavedItem, error)

		wantCode  int
		wantError *jsonErr
		wantItems []*SavedItem
	}{
		{
			"123456",
			func(id uint64) ([]*SavedItem, error) {
				if id != 123456 {
					t.Errorf("mockget expected id of 123456; got %d", id)
				}
				return []*SavedItem{
					&SavedItem{
						123456,
						"http://nytimes.com/saved/item",
						testDate,
					},
				}, nil
			},

			http.StatusOK,
			&jsonErr{},
			[]*SavedItem{
				&SavedItem{
					123456,
					"http://nytimes.com/saved/item",
					testDate,
				},
			},
		},
		{
			"",
			func(id uint64) ([]*SavedItem, error) {
				if id != 123456 {
					t.Errorf("mockget expected id of 123456; got %d", id)
				}
				return []*SavedItem{
					&SavedItem{
						123456,
						"http://nytimes.com/saved/item",
						testDate,
					},
				}, nil
			},

			http.StatusUnauthorized,
			UnauthErr,
			[]*SavedItem(nil),
		},
		{
			"123456",
			func(id uint64) ([]*SavedItem, error) {
				if id != 123456 {
					t.Errorf("mockget expected id of 123456; got %d", id)
				}
				return []*SavedItem{}, errors.New("nope")
			},

			http.StatusServiceUnavailable,
			ServiceUnavailableErr,
			[]*SavedItem(nil),
		},
	}

	for testnum, test := range tests {

		// create a new Gizmo simple server
		ss := server.NewSimpleServer(nil)
		// create our test repo implementation
		testRepo := &testSavedItemsRepo{MockGet: test.givenRepo}
		// inject the test repo into a new SavedItemsService
		sis := &SavedItemsService{testRepo}
		// register the service with our simple server
		ss.Register(sis)

		// set up the w and r to pass into our server
		w := httptest.NewRecorder()
		r, _ := http.NewRequest("GET", "/svc/saved-items", nil)
		if test.givenID != "" {
			r.Header.Set("USER_ID", test.givenID)
		}

		// run the test by passing a request we expect to hit our endpoint
		// into the simple server's ServeHTTP method.
		ss.ServeHTTP(w, r)

		// first test validation: check the HTTP response code
		if w.Code != test.wantCode {
			t.Errorf("expected status code of %d; got %d", test.wantCode, w.Code)
		}

		// get the body of the response to inspect
		bod := w.Body.Bytes()

		// if we were expecting an error scenario, marshal the response
		// JSON into an error to compare with what we want.
		var gotErr *jsonErr
		json.Unmarshal(bod, &gotErr)
		if !reflect.DeepEqual(gotErr, test.wantError) {
			t.Errorf("expected status response of '%#v'; got '%#v'", test.wantError, gotErr)
		}

		// if we expect a normal response, compare it to our wanted response struct
		var got []*SavedItem
		json.Unmarshal(bod, &got)
		if !reflect.DeepEqual(got, test.wantItems) {
			t.Errorf("TEST[%d] expected items of \n%#v; got \n%#v", testnum, test.wantItems, got)
		}

		// ** THIS IS REQUIRED in order to run the test multiple times.
		metrics.DefaultRegistry.UnregisterAll()
	}
}
Example #12
0
func TestGetCats(t *testing.T) {
	tests := []struct {
		given      string
		givenError error

		wantCode      int
		wantPublished []nyt.SemanticConceptArticle
	}{
		{
			`{"url":"http://www.nytiems.com/cats-article","title":"cats cats cats"}`,
			nil,

			http.StatusOK,
			[]nyt.SemanticConceptArticle{
				nyt.SemanticConceptArticle{
					Url:   "http://www.nytiems.com/cats-article",
					Title: "cats cats cats",
				},
			},
		},
		{
			`{"url":"http://www.nytiems.com/cats-article","title":"cats cats cats"}`,
			errors.New("NOPE!"),

			http.StatusServiceUnavailable,
			[]nyt.SemanticConceptArticle{
				nyt.SemanticConceptArticle{
					Url:   "http://www.nytiems.com/cats-article",
					Title: "cats cats cats",
				},
			},
		},
		{
			`"cats cats cats"`,
			nil,

			http.StatusServiceUnavailable,
			[]nyt.SemanticConceptArticle{},
		},
	}

	for _, test := range tests {

		srvr := server.NewSimpleServer(nil)
		pub := &pubsubtest.TestPublisher{GivenError: test.givenError}
		srvr.Register(&JSONPubService{pub: pub})

		r, _ := http.NewRequest("PUT", "/svc/nyt/cats", bytes.NewBufferString(test.given))
		w := httptest.NewRecorder()
		srvr.ServeHTTP(w, r)

		if w.Code != test.wantCode {
			t.Errorf("expected response code of %d; got %d", test.wantCode, w.Code)
		}

		if len(pub.Published) != len(test.wantPublished) {
			t.Errorf("expected %d published messages, got %d: ", len(pub.Published), len(test.wantPublished))
		}

		for idx, wantPub := range test.wantPublished {
			var got nyt.SemanticConceptArticle
			proto.Unmarshal(pub.Published[idx].Body, &got)
			if !reflect.DeepEqual(got, wantPub) {
				t.Errorf("expected response body of\n%#v;\ngot\n%#v", wantPub, got)
			}
		}

		// ** THIS IS REQUIRED in order to run the test multiple times.
		metrics.DefaultRegistry.UnregisterAll()
	}

}
Example #13
0
func TestDelete(t *testing.T) {

	tests := []struct {
		givenID   string
		givenURL  string
		givenRepo func(uint64, string) error

		wantCode  int
		wantError *jsonErr
		wantResp  *jsonResponse
	}{
		{
			"123456",
			"http://nytimes.com/article",
			func(id uint64, url string) error {
				if id != 123456 {
					t.Errorf("MockDelete expected id of 123456; got %d", id)
				}
				if url != "http://nytimes.com/article" {
					t.Errorf("MockDelete expected url of `http://nytimes.com/aritcle'; got %s", url)
				}
				return nil
			},

			http.StatusOK,
			&jsonErr{},
			&jsonResponse{"successfully deleted saved item"},
		},
		{
			"123456",
			"http://nytimes.com/article",
			func(id uint64, url string) error {
				if id != 123456 {
					t.Errorf("MockDelete expected id of 123456; got %d", id)
				}
				if url != "http://nytimes.com/article" {
					t.Errorf("MockDelete expected url of `http://nytimes.com/aritcle'; got %s", url)
				}
				return errors.New("nope")
			},

			http.StatusServiceUnavailable,
			ServiceUnavailableErr,
			&jsonResponse{},
		},
		{
			"",
			"http://nytimes.com/article",
			func(id uint64, url string) error {
				t.Error("MockDelete should not have been called in this scenario!")
				return nil
			},

			http.StatusUnauthorized,
			UnauthErr,
			&jsonResponse{},
		},
	}

	for _, test := range tests {

		// create a new Gizmo simple server
		ss := server.NewSimpleServer(nil)
		// create our test repo implementation
		testRepo := &testSavedItemsRepo{MockDelete: test.givenRepo}
		// inject the test repo into a new SavedItemsService
		sis := &SavedItemsService{testRepo}
		// register the service with our simple server
		ss.Register(sis)

		// set up the w and r to pass into our server
		w := httptest.NewRecorder()
		r, _ := http.NewRequest("DELETE", "/svc/saved-items?url="+test.givenURL, nil)
		if test.givenID != "" {
			r.Header.Set("USER_ID", test.givenID)
		}

		// run the test by passing a request we expect to hit our endpoint
		// into the simple server's ServeHTTP method.
		ss.ServeHTTP(w, r)

		// first test validation: check the HTTP response code
		if w.Code != test.wantCode {
			t.Errorf("expected status code of %d; got %d", test.wantCode, w.Code)
		}

		// get the body of the response to inspect
		bod := w.Body.Bytes()

		// if we were expecting an error scenario, marshal the response
		// JSON into an error to compare with what we want.
		var gotErr *jsonErr
		json.Unmarshal(bod, &gotErr)
		if !reflect.DeepEqual(gotErr, test.wantError) {
			t.Errorf("expected status response of '%#v'; got '%#v'", test.wantError, gotErr)
		}

		// if we expect a normal response, compare it to our wanted response struct
		var got *jsonResponse
		json.Unmarshal(bod, &got)
		if !reflect.DeepEqual(got, test.wantResp) {
			t.Errorf("expected response of \n%#v; got \n%#v", test.wantResp, got)
		}
	}
}