github.com/iron-io/functions@v0.0.0-20180820112432-d59d7d1c40b2/api/server/apps_test.go (about)

     1  // +build server
     2  
     3  package server
     4  
     5  import (
     6  	"bytes"
     7  	"log"
     8  	"net/http"
     9  	"strings"
    10  	"testing"
    11  
    12  	"github.com/Sirupsen/logrus"
    13  	"github.com/gin-gonic/gin"
    14  	"github.com/iron-io/functions/api/datastore"
    15  	"github.com/iron-io/functions/api/models"
    16  	"github.com/iron-io/functions/api/mqs"
    17  	"github.com/iron-io/functions/api/runner/task"
    18  )
    19  
    20  func setLogBuffer() *bytes.Buffer {
    21  	var buf bytes.Buffer
    22  	buf.WriteByte('\n')
    23  	logrus.SetOutput(&buf)
    24  	gin.DefaultErrorWriter = &buf
    25  	gin.DefaultWriter = &buf
    26  	log.SetOutput(&buf)
    27  	return &buf
    28  }
    29  
    30  func mockTasksConduit() chan task.Request {
    31  	tasks := make(chan task.Request)
    32  	go func() {
    33  		for range tasks {
    34  		}
    35  	}()
    36  	return tasks
    37  }
    38  
    39  func TestAppCreate(t *testing.T) {
    40  	buf := setLogBuffer()
    41  	tasks := mockTasksConduit()
    42  	defer close(tasks)
    43  	for i, test := range []struct {
    44  		mock          models.Datastore
    45  		path          string
    46  		body          string
    47  		expectedCode  int
    48  		expectedError error
    49  	}{
    50  		// errors
    51  		{datastore.NewMock(), "/v1/apps", ``, http.StatusBadRequest, models.ErrInvalidJSON},
    52  		{datastore.NewMock(), "/v1/apps", `{}`, http.StatusBadRequest, models.ErrAppsMissingNew},
    53  		{datastore.NewMock(), "/v1/apps", `{ "name": "Test" }`, http.StatusBadRequest, models.ErrAppsMissingNew},
    54  		{datastore.NewMock(), "/v1/apps", `{ "app": { "name": "" } }`, http.StatusInternalServerError, models.ErrAppsValidationMissingName},
    55  		{datastore.NewMock(), "/v1/apps", `{ "app": { "name": "1234567890123456789012345678901" } }`, http.StatusInternalServerError, models.ErrAppsValidationTooLongName},
    56  		{datastore.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
    57  		{datastore.NewMock(), "/v1/apps", `{ "app": { "name": "&&%@!#$#@$" } }`, http.StatusInternalServerError, models.ErrAppsValidationInvalidName},
    58  
    59  		// success
    60  		{datastore.NewMock(), "/v1/apps", `{ "app": { "name": "teste" } }`, http.StatusOK, nil},
    61  	} {
    62  		rnr, cancel := testRunner(t)
    63  		srv := testServer(test.mock, &mqs.Mock{}, rnr, tasks)
    64  		router := srv.Router
    65  
    66  		body := bytes.NewBuffer([]byte(test.body))
    67  		_, rec := routerRequest(t, router, "POST", test.path, body)
    68  
    69  		if rec.Code != test.expectedCode {
    70  			t.Log(buf.String())
    71  			t.Errorf("Test %d: Expected status code to be %d but was %d",
    72  				i, test.expectedCode, rec.Code)
    73  		}
    74  
    75  		if test.expectedError != nil {
    76  			resp := getErrorResponse(t, rec)
    77  
    78  			if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
    79  				t.Log(buf.String())
    80  				t.Errorf("Test %d: Expected error message to have `%s`",
    81  					i, test.expectedError.Error())
    82  			}
    83  		}
    84  		cancel()
    85  	}
    86  }
    87  
    88  func TestAppDelete(t *testing.T) {
    89  	buf := setLogBuffer()
    90  	tasks := mockTasksConduit()
    91  	defer close(tasks)
    92  
    93  	for i, test := range []struct {
    94  		ds            models.Datastore
    95  		path          string
    96  		body          string
    97  		expectedCode  int
    98  		expectedError error
    99  	}{
   100  		{datastore.NewMock(), "/v1/apps/myapp", "", http.StatusNotFound, nil},
   101  		{datastore.NewMockInit(
   102  			[]*models.App{{
   103  				Name: "myapp",
   104  			}}, nil,
   105  		), "/v1/apps/myapp", "", http.StatusOK, nil},
   106  	} {
   107  		rnr, cancel := testRunner(t)
   108  		srv := testServer(test.ds, &mqs.Mock{}, rnr, tasks)
   109  
   110  		_, rec := routerRequest(t, srv.Router, "DELETE", test.path, nil)
   111  
   112  		if rec.Code != test.expectedCode {
   113  			t.Log(buf.String())
   114  			t.Errorf("Test %d: Expected status code to be %d but was %d",
   115  				i, test.expectedCode, rec.Code)
   116  		}
   117  
   118  		if test.expectedError != nil {
   119  			resp := getErrorResponse(t, rec)
   120  
   121  			if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
   122  				t.Log(buf.String())
   123  				t.Errorf("Test %d: Expected error message to have `%s`",
   124  					i, test.expectedError.Error())
   125  			}
   126  		}
   127  		cancel()
   128  	}
   129  }
   130  
   131  func TestAppList(t *testing.T) {
   132  	buf := setLogBuffer()
   133  	tasks := mockTasksConduit()
   134  	defer close(tasks)
   135  
   136  	rnr, cancel := testRunner(t)
   137  	defer cancel()
   138  	srv := testServer(datastore.NewMock(), &mqs.Mock{}, rnr, tasks)
   139  
   140  	for i, test := range []struct {
   141  		path          string
   142  		body          string
   143  		expectedCode  int
   144  		expectedError error
   145  	}{
   146  		{"/v1/apps", "", http.StatusOK, nil},
   147  	} {
   148  		_, rec := routerRequest(t, srv.Router, "GET", test.path, nil)
   149  
   150  		if rec.Code != test.expectedCode {
   151  			t.Log(buf.String())
   152  			t.Errorf("Test %d: Expected status code to be %d but was %d",
   153  				i, test.expectedCode, rec.Code)
   154  		}
   155  
   156  		if test.expectedError != nil {
   157  			resp := getErrorResponse(t, rec)
   158  
   159  			if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
   160  				t.Log(buf.String())
   161  				t.Errorf("Test %d: Expected error message to have `%s`",
   162  					i, test.expectedError.Error())
   163  			}
   164  		}
   165  	}
   166  }
   167  
   168  func TestAppGet(t *testing.T) {
   169  	buf := setLogBuffer()
   170  	tasks := mockTasksConduit()
   171  	defer close(tasks)
   172  
   173  	rnr, cancel := testRunner(t)
   174  	defer cancel()
   175  	srv := testServer(datastore.NewMock(), &mqs.Mock{}, rnr, tasks)
   176  
   177  	for i, test := range []struct {
   178  		path          string
   179  		body          string
   180  		expectedCode  int
   181  		expectedError error
   182  	}{
   183  		{"/v1/apps/myapp", "", http.StatusNotFound, nil},
   184  	} {
   185  		_, rec := routerRequest(t, srv.Router, "GET", test.path, nil)
   186  
   187  		if rec.Code != test.expectedCode {
   188  			t.Log(buf.String())
   189  			t.Errorf("Test %d: Expected status code to be %d but was %d",
   190  				i, test.expectedCode, rec.Code)
   191  		}
   192  
   193  		if test.expectedError != nil {
   194  			resp := getErrorResponse(t, rec)
   195  
   196  			if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
   197  				t.Log(buf.String())
   198  				t.Errorf("Test %d: Expected error message to have `%s`",
   199  					i, test.expectedError.Error())
   200  			}
   201  		}
   202  	}
   203  }
   204  
   205  func TestAppUpdate(t *testing.T) {
   206  	buf := setLogBuffer()
   207  	tasks := mockTasksConduit()
   208  	defer close(tasks)
   209  
   210  	for i, test := range []struct {
   211  		mock          models.Datastore
   212  		path          string
   213  		body          string
   214  		expectedCode  int
   215  		expectedError error
   216  	}{
   217  		// errors
   218  		{datastore.NewMock(), "/v1/apps/myapp", ``, http.StatusBadRequest, models.ErrInvalidJSON},
   219  
   220  		// success
   221  		{datastore.NewMockInit(
   222  			[]*models.App{{
   223  				Name: "myapp",
   224  			}}, nil,
   225  		), "/v1/apps/myapp", `{ "app": { "config": { "test": "1" } } }`, http.StatusOK, nil},
   226  
   227  		// Addresses #380
   228  		{datastore.NewMockInit(
   229  			[]*models.App{{
   230  				Name: "myapp",
   231  			}}, nil,
   232  		), "/v1/apps/myapp", `{ "app": { "name": "othername" } }`, http.StatusBadRequest, nil},
   233  	} {
   234  		rnr, cancel := testRunner(t)
   235  		srv := testServer(test.mock, &mqs.Mock{}, rnr, tasks)
   236  
   237  		body := bytes.NewBuffer([]byte(test.body))
   238  		_, rec := routerRequest(t, srv.Router, "PATCH", test.path, body)
   239  
   240  		if rec.Code != test.expectedCode {
   241  			t.Log(buf.String())
   242  			t.Errorf("Test %d: Expected status code to be %d but was %d",
   243  				i, test.expectedCode, rec.Code)
   244  		}
   245  
   246  		if test.expectedError != nil {
   247  			resp := getErrorResponse(t, rec)
   248  
   249  			if !strings.Contains(resp.Error.Message, test.expectedError.Error()) {
   250  				t.Log(buf.String())
   251  				t.Errorf("Test %d: Expected error message to have `%s`",
   252  					i, test.expectedError.Error())
   253  			}
   254  		}
   255  
   256  		cancel()
   257  	}
   258  }