github.com/liftedinit/mfx-migrator@v0.0.1-alpha.1/cmd/claim_test.go (about)

     1  package cmd_test
     2  
     3  import (
     4  	"context"
     5  	"os"
     6  	"testing"
     7  
     8  	"github.com/go-resty/resty/v2"
     9  	"github.com/jarcoal/httpmock"
    10  	"github.com/spf13/cobra"
    11  	"github.com/stretchr/testify/require"
    12  
    13  	"github.com/liftedinit/mfx-migrator/internal/store"
    14  
    15  	"github.com/liftedinit/mfx-migrator/cmd"
    16  	"github.com/liftedinit/mfx-migrator/testutils"
    17  )
    18  
    19  func TestClaimCmd(t *testing.T) {
    20  	tmpdir := t.TempDir()
    21  	if err := os.Chdir(tmpdir); err != nil {
    22  		t.Fatal(err)
    23  	}
    24  
    25  	workItemPath := tmpdir + "/" + testutils.Uuid + ".json"
    26  
    27  	var slice []string
    28  	urlArg := append(slice, []string{"--url", testutils.RootUrl}...)
    29  	usernameArg := append(urlArg, []string{"--username", "user"}...)
    30  	passwordArg := append(usernameArg, []string{"--password", "pass"}...)
    31  	neighborhoodArg := append(passwordArg, []string{"--neighborhood", "1"}...)
    32  
    33  	tt := []struct {
    34  		name      string
    35  		args      []string
    36  		err       string
    37  		expected  string
    38  		endpoints []testutils.HttpResponder
    39  	}{
    40  		{name: "no argument", args: []string{}, err: "URL cannot be empty"},
    41  		{name: "username missing", args: urlArg, err: "username is required"},
    42  		{name: "password missing", args: usernameArg, err: "password is required"},
    43  		{name: "claim from queue (default neighborhood)", args: passwordArg, endpoints: []testutils.HttpResponder{
    44  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.AuthResponder},
    45  			{Method: "PUT", Url: testutils.DefaultClaimUrl, Responder: testutils.MigrationClaimResponder(1, store.CLAIMED)},
    46  		}, expected: "Work item claimed"},
    47  		{name: "claim from queue (neighborhood == 1)", args: neighborhoodArg, endpoints: []testutils.HttpResponder{
    48  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.AuthResponder},
    49  			{Method: "PUT", Url: "=~^" + testutils.ClaimUrl, Responder: testutils.MigrationClaimResponder(1, store.CLAIMED)},
    50  		}, expected: "Work item claimed"},
    51  		{name: "auth endpoint not found", args: neighborhoodArg, endpoints: []testutils.HttpResponder{
    52  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.NotFoundResponder},
    53  		}, err: "response status code: 404"},
    54  		{name: "unable to claim from queue (no work items available)", args: neighborhoodArg, endpoints: []testutils.HttpResponder{
    55  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.AuthResponder},
    56  			{Method: "PUT", Url: testutils.ClaimUrl, Responder: testutils.MigrationClaimResponder(0, store.CLAIMED)},
    57  		}, expected: "No work items available"},
    58  		{name: "claim from uuid", args: append(neighborhoodArg, []string{"--uuid", testutils.DummyUUIDStr}...), endpoints: []testutils.HttpResponder{
    59  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.AuthResponder},
    60  			{Method: "PUT", Url: "=~^" + testutils.ClaimUuidUrl, Responder: testutils.MigrationClaimOneResponder(store.CLAIMED)},
    61  		}, expected: "Work item claimed"},
    62  		{name: "unable to claim from uuid (not found)", args: append(neighborhoodArg, []string{"--uuid", testutils.DummyUUIDStr}...), endpoints: []testutils.HttpResponder{
    63  			{Method: "POST", Url: testutils.LoginUrl, Responder: testutils.AuthResponder},
    64  			{Method: "PUT", Url: "=~^" + testutils.ClaimUuidUrl, Responder: testutils.NotFoundResponder},
    65  		}, err: "response status code: 404"},
    66  	}
    67  	for _, tc := range tt {
    68  		command := &cobra.Command{Use: "claim", PersistentPreRunE: cmd.RootCmdPersistentPreRunE, RunE: cmd.ClaimCmdRunE}
    69  
    70  		// Create a new resty client and inject it into the command context
    71  		client := resty.New()
    72  		ctx := context.WithValue(context.Background(), cmd.RestyClientKey, client)
    73  		command.SetContext(ctx)
    74  
    75  		// Enable http mocking on the resty client
    76  		httpmock.ActivateNonDefault(client.GetClient())
    77  		cmd.SetupRootCmdFlags(command)
    78  		cmd.SetupClaimCmdFlags(command)
    79  
    80  		t.Run(tc.name, func(t *testing.T) {
    81  			for _, endpoint := range tc.endpoints {
    82  				httpmock.RegisterResponder(endpoint.Method, endpoint.Url, endpoint.Responder)
    83  			}
    84  
    85  			out, err := testutils.Execute(t, command, tc.args...)
    86  			t.Log(out)
    87  
    88  			if tc.err == "" {
    89  				require.Contains(t, out, tc.expected)
    90  			} else {
    91  				require.ErrorContains(t, err, tc.err)
    92  			}
    93  			httpmock.Reset()
    94  		})
    95  
    96  		// Remove the work item file if it exists
    97  		_, err := os.Stat(workItemPath)
    98  		if !os.IsNotExist(err) {
    99  			err = os.Remove(workItemPath)
   100  			require.NoError(t, err)
   101  		}
   102  	}
   103  }