github.com/nais/knorten@v0.0.0-20240104110906-55926958e361/pkg/api/compute_test.go (about)

     1  package api
     2  
     3  import (
     4  	"context"
     5  	"encoding/json"
     6  	"fmt"
     7  	"io"
     8  	"net/http"
     9  	"net/url"
    10  	"strconv"
    11  	"testing"
    12  
    13  	"github.com/google/go-cmp/cmp"
    14  	"github.com/nais/knorten/pkg/database"
    15  	"github.com/nais/knorten/pkg/database/gensql"
    16  )
    17  
    18  func TestComputeAPI(t *testing.T) {
    19  	ctx := context.Background()
    20  
    21  	t.Run("create compute", func(t *testing.T) {
    22  		oldEvents, err := repo.EventsGetType(ctx, database.EventTypeCreateCompute)
    23  		if err != nil {
    24  			t.Error(err)
    25  		}
    26  
    27  		resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/new", server.URL), nil)
    28  		if err != nil {
    29  			t.Error(err)
    30  		}
    31  		defer resp.Body.Close()
    32  
    33  		events, err := repo.EventsGetType(ctx, database.EventTypeCreateCompute)
    34  		if err != nil {
    35  			t.Error(err)
    36  		}
    37  
    38  		newEvents := getNewEvents(oldEvents, events)
    39  		eventPayload, err := getComputeEvent(newEvents, testUser.Email)
    40  		if err != nil {
    41  			t.Error(err)
    42  		}
    43  
    44  		if eventPayload.Owner == "" {
    45  			t.Errorf("create compute: no event registered for user %v", testUser.Email)
    46  		}
    47  
    48  		if eventPayload.Owner != testUser.Email {
    49  			t.Errorf("create compute: email expected %v, got %v", testUser.Email, eventPayload.Owner)
    50  		}
    51  
    52  		if eventPayload.Name != "compute-"+getNormalizedNameFromEmail(testUser.Email) {
    53  			t.Errorf("create compute: name expected %v, got %v", "compute-"+getNormalizedNameFromEmail(testUser.Email), eventPayload.Name)
    54  		}
    55  	})
    56  
    57  	t.Run("resize compute disk", func(t *testing.T) {
    58  		instance := gensql.ComputeInstance{
    59  			Owner:    testUser.Email,
    60  			Name:     "compute-" + getNormalizedNameFromEmail(testUser.Email),
    61  			DiskSize: 10,
    62  		}
    63  		if err := repo.ComputeInstanceCreate(ctx, instance); err != nil {
    64  			t.Error(err)
    65  		}
    66  
    67  		t.Cleanup(func() {
    68  			if err := repo.ComputeInstanceDelete(ctx, testUser.Email); err != nil {
    69  				t.Error(err)
    70  			}
    71  		})
    72  
    73  		oldEvents, err := repo.EventsGetType(ctx, database.EventTypeResizeCompute)
    74  		if err != nil {
    75  			t.Error(err)
    76  		}
    77  
    78  		diskSize := 200
    79  		data := url.Values{"diskSize": {strconv.Itoa(diskSize)}}
    80  		resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/edit", server.URL), data)
    81  		if err != nil {
    82  			t.Error(err)
    83  		}
    84  		defer resp.Body.Close()
    85  
    86  		events, err := repo.EventsGetType(ctx, database.EventTypeResizeCompute)
    87  		if err != nil {
    88  			t.Error(err)
    89  		}
    90  
    91  		newEvents := getNewEvents(oldEvents, events)
    92  		eventPayload, err := getComputeEvent(newEvents, testUser.Email)
    93  		if err != nil {
    94  			t.Error(err)
    95  		}
    96  
    97  		if eventPayload.Owner == "" {
    98  			t.Errorf("resize compute disk: no event registered for user %v", testUser.Email)
    99  		}
   100  
   101  		if eventPayload.Owner != testUser.Email {
   102  			t.Errorf("resize compute disk: email expected %v, got %v", testUser.Email, eventPayload.Owner)
   103  		}
   104  
   105  		if eventPayload.Name != "compute-"+getNormalizedNameFromEmail(testUser.Email) {
   106  			t.Errorf("resize compute disk: name expected %v, got %v", "compute-"+getNormalizedNameFromEmail(testUser.Email), eventPayload.Name)
   107  		}
   108  
   109  		if eventPayload.DiskSize != int32(diskSize) {
   110  			t.Errorf("resize compute disk: diskSize expected %v, got %v", diskSize, eventPayload.DiskSize)
   111  		}
   112  	})
   113  
   114  	t.Run("get edit compute html", func(t *testing.T) {
   115  		instance := gensql.ComputeInstance{
   116  			Owner:    testUser.Email,
   117  			Name:     "compute-" + getNormalizedNameFromEmail(testUser.Email),
   118  			DiskSize: 100,
   119  		}
   120  		if err := repo.ComputeInstanceCreate(ctx, instance); err != nil {
   121  			t.Error(err)
   122  		}
   123  
   124  		t.Cleanup(func() {
   125  			if err := repo.ComputeInstanceDelete(ctx, testUser.Email); err != nil {
   126  				t.Error(err)
   127  			}
   128  		})
   129  
   130  		resp, err := server.Client().Get(fmt.Sprintf("%v/compute/edit", server.URL))
   131  		if err != nil {
   132  			t.Error(err)
   133  		}
   134  		defer resp.Body.Close()
   135  
   136  		if resp.StatusCode != http.StatusOK {
   137  			t.Errorf("Status code is %v, should be %v", resp.StatusCode, http.StatusOK)
   138  		}
   139  
   140  		if resp.Header.Get("Content-Type") != htmlContentType {
   141  			t.Errorf("Content-Type header is %v, should be %v", resp.Header.Get("Content-Type"), htmlContentType)
   142  		}
   143  
   144  		received, err := io.ReadAll(resp.Body)
   145  		if err != nil {
   146  			t.Error(err)
   147  		}
   148  		receivedMinimized, err := minimizeHTML(string(received))
   149  		if err != nil {
   150  			t.Error(err)
   151  		}
   152  
   153  		expected, err := createExpectedHTML("compute/edit", map[string]any{
   154  			"name":     instance.Name,
   155  			"diskSize": instance.DiskSize,
   156  		})
   157  		if err != nil {
   158  			t.Error(err)
   159  		}
   160  		expectedMinimized, err := minimizeHTML(expected)
   161  		if err != nil {
   162  			t.Error(err)
   163  		}
   164  
   165  		if diff := cmp.Diff(expectedMinimized, receivedMinimized); diff != "" {
   166  			t.Errorf("mismatch (-want +got):\n%s", diff)
   167  		}
   168  	})
   169  
   170  	t.Run("delete compute", func(t *testing.T) {
   171  		resp, err := server.Client().PostForm(fmt.Sprintf("%v/compute/delete", server.URL), nil)
   172  		if err != nil {
   173  			t.Error(err)
   174  		}
   175  		defer resp.Body.Close()
   176  
   177  		events, err := repo.EventsGetType(ctx, database.EventTypeDeleteCompute)
   178  		if err != nil {
   179  			t.Error(err)
   180  		}
   181  
   182  		if !deleteEventCreatedForTeam(events, testUser.Email) {
   183  			t.Errorf("delete compute: no event registered for user %v", testUser.Email)
   184  		}
   185  	})
   186  }
   187  
   188  func getComputeEvent(events []gensql.Event, user string) (gensql.ComputeInstance, error) {
   189  	for _, event := range events {
   190  		payload := gensql.ComputeInstance{}
   191  		err := json.Unmarshal(event.Payload, &payload)
   192  		if err != nil {
   193  			return gensql.ComputeInstance{}, err
   194  		}
   195  
   196  		if payload.Owner == user {
   197  			return payload, nil
   198  		}
   199  	}
   200  
   201  	return gensql.ComputeInstance{}, nil
   202  }