github.com/tonkpils/cli@v1.6.2/api_test.go (about)

     1  package main
     2  
     3  import (
     4  	"encoding/json"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"testing"
    10  
    11  	"github.com/exercism/cli/configuration"
    12  	"github.com/stretchr/testify/assert"
    13  )
    14  
    15  var assignmentsJson = `
    16  {
    17      "assignments": [
    18          {
    19              "track": "ruby",
    20              "slug": "bob",
    21  						"files": {
    22  							"README.md": "Readme text",
    23  							"bob_test.rb": "Tests text"
    24  						}
    25          }
    26      ]
    27  }
    28  `
    29  
    30  var fetchHandler = func(rw http.ResponseWriter, r *http.Request) {
    31  	r.ParseForm()
    32  	apiKey := r.Form.Get("key")
    33  	if r.URL.Path != "/api/v1/user/assignments/current" {
    34  		fmt.Println("Not found")
    35  		rw.WriteHeader(http.StatusNotFound)
    36  		return
    37  	}
    38  	if apiKey != "myApiKey" {
    39  		rw.WriteHeader(http.StatusUnauthorized)
    40  		fmt.Fprintf(rw, `{"error": "Unable to identify user"}`)
    41  		return
    42  	}
    43  
    44  	rw.Header().Set("Content-Type", "application/json")
    45  	fmt.Fprintf(rw, assignmentsJson)
    46  }
    47  
    48  func TestFetchWithKey(t *testing.T) {
    49  	server := httptest.NewServer(http.HandlerFunc(fetchHandler))
    50  
    51  	config := configuration.Config{
    52  		Hostname: server.URL,
    53  		ApiKey:   "myApiKey",
    54  	}
    55  
    56  	assignments, err := FetchAssignments(config, "/api/v1/user/assignments/current")
    57  	assert.NoError(t, err)
    58  
    59  	assert.Equal(t, len(assignments), 1)
    60  
    61  	assert.Equal(t, assignments[0].Track, "ruby")
    62  	assert.Equal(t, assignments[0].Slug, "bob")
    63  	assert.Equal(t, assignments[0].Files, map[string]string{
    64  		"README.md":   "Readme text",
    65  		"bob_test.rb": "Tests text",
    66  	},
    67  	)
    68  
    69  	server.Close()
    70  }
    71  
    72  func TestFetchWithIncorrectKey(t *testing.T) {
    73  	server := httptest.NewServer(http.HandlerFunc(fetchHandler))
    74  
    75  	config := configuration.Config{
    76  		Hostname: server.URL,
    77  		ApiKey:   "myWrongApiKey",
    78  	}
    79  
    80  	assignments, err := FetchAssignments(config, "/api/v1/user/assignments/current")
    81  
    82  	assert.Error(t, err)
    83  	assert.Equal(t, len(assignments), 0)
    84  	assert.Contains(t, fmt.Sprintf("%s", err), "Unable to identify user")
    85  
    86  	server.Close()
    87  }
    88  
    89  var submitHandler = func(rw http.ResponseWriter, r *http.Request) {
    90  	pathMatches := r.URL.Path == "/api/v1/user/assignments"
    91  	methodMatches := r.Method == "POST"
    92  	if !(pathMatches && methodMatches) {
    93  		rw.WriteHeader(http.StatusNotFound)
    94  		return
    95  	}
    96  
    97  	userAgentMatches := r.Header.Get("User-Agent") == fmt.Sprintf("github.com/exercism/cli v%s", VERSION)
    98  
    99  	if !userAgentMatches {
   100  		fmt.Printf("User agent mismatch: %s\n", r.Header.Get("User-Agent"))
   101  		rw.WriteHeader(http.StatusInternalServerError)
   102  		return
   103  	}
   104  
   105  	body, err := ioutil.ReadAll(r.Body)
   106  	r.Body.Close()
   107  
   108  	if err != nil {
   109  		rw.WriteHeader(http.StatusInternalServerError)
   110  		fmt.Printf("Reading body error: %s\n", err)
   111  		return
   112  	}
   113  
   114  	type Submission struct {
   115  		Key  string
   116  		Code string
   117  		Path string
   118  	}
   119  
   120  	submission := Submission{}
   121  
   122  	err = json.Unmarshal(body, &submission)
   123  	if err != nil {
   124  		fmt.Printf("Unmarshalling error: %v, Body: %s\n", err, body)
   125  		rw.WriteHeader(http.StatusInternalServerError)
   126  		return
   127  	}
   128  
   129  	if submission.Key != "myApiKey" {
   130  		rw.WriteHeader(http.StatusForbidden)
   131  		rw.Header().Set("Content-Type", "application/json")
   132  		fmt.Fprintf(rw, `{"error": "Unable to identify user"}`)
   133  		return
   134  	}
   135  
   136  	code := submission.Code
   137  	filePath := submission.Path
   138  
   139  	codeMatches := string(code) == "My source code\n"
   140  	filePathMatches := filePath == "ruby/bob/bob.rb"
   141  
   142  	if !filePathMatches {
   143  		fmt.Printf("FilePathMismatch: File Path: %s\n", filePath)
   144  		rw.WriteHeader(http.StatusBadRequest)
   145  		return
   146  	}
   147  
   148  	if !codeMatches {
   149  		fmt.Printf("Code Mismatch: Code: %v\n", code)
   150  		rw.WriteHeader(http.StatusBadRequest)
   151  		return
   152  	}
   153  
   154  	rw.WriteHeader(http.StatusCreated)
   155  	rw.Header().Set("Content-Type", "application/json")
   156  
   157  	submitJson := `
   158  {
   159  	"status":"saved",
   160  	"language":"ruby",
   161  	"exercise":"bob",
   162  	"submission_path":"/username/ruby/bob"
   163  }
   164  `
   165  	fmt.Fprintf(rw, submitJson)
   166  }
   167  
   168  func TestSubmitWithKey(t *testing.T) {
   169  	server := httptest.NewServer(http.HandlerFunc(submitHandler))
   170  	defer server.Close()
   171  
   172  	var code = []byte("My source code\n")
   173  	config := configuration.Config{
   174  		Hostname: server.URL,
   175  		ApiKey:   "myApiKey",
   176  	}
   177  	response, err := SubmitAssignment(config, "ruby/bob/bob.rb", code)
   178  	assert.NoError(t, err)
   179  
   180  	assert.Equal(t, response.Status, "saved")
   181  	assert.Equal(t, response.Language, "ruby")
   182  	assert.Equal(t, response.Exercise, "bob")
   183  	assert.Equal(t, response.SubmissionPath, "/username/ruby/bob")
   184  }
   185  
   186  func TestSubmitWithIncorrectKey(t *testing.T) {
   187  	server := httptest.NewServer(http.HandlerFunc(submitHandler))
   188  	defer server.Close()
   189  
   190  	config := configuration.Config{
   191  		Hostname: server.URL,
   192  		ApiKey:   "myWrongApiKey",
   193  	}
   194  
   195  	var code = []byte("My source code\n")
   196  	_, err := SubmitAssignment(config, "ruby/bob/bob.rb", code)
   197  
   198  	assert.Error(t, err)
   199  }