package rest_api_test

// Docs:
// - Endpoint: https://developer.salesforce.com/docs/atlas.en-us.254.0.api_rest.meta/api_rest/resources_limits.htm
// - Request: https://developer.salesforce.com/docs/atlas.en-us.254.0.api_rest.meta/api_rest/resources_limits.htm
// - Response: https://developer.salesforce.com/docs/atlas.en-us.254.0.api_rest.meta/api_rest/resources_limits.htm
// - Sub-schema: https://developer.salesforce.com/docs/atlas.en-us.254.0.api_rest.meta/api_rest/resources_limits.htm
// - Errors: https://developer.salesforce.com/docs/atlas.en-us.api_rest.meta/api_rest/intro_rest.htm

import (
	"net/http"
	"testing"

	"github.com/nexuscrm/tests/contract/internal/liveapi"
	"github.com/stretchr/testify/assert"
	"github.com/stretchr/testify/require"
)

func TestGetLimits(t *testing.T) {
	testCases := []struct {
		name    string
		arrange func(t *testing.T) string
		act     func(t *testing.T, path string) *http.Response
		assert  func(t *testing.T, resp *http.Response)
	}{
		{
			name: "limits document includes daily API allocation",
			// Doc: https://developer.salesforce.com/docs/atlas.en-us.254.0.api_rest.meta/api_rest/resources_limits.htm
			arrange: func(t *testing.T) string {
				return "/limits"
			},
			act: func(t *testing.T, path string) *http.Response {
				client := liveapi.NewAuthenticatedClient(t)
				resp, err := client.DoJSON(http.MethodGet, path, nil)
				require.NoError(t, err)
				return resp
			},
			assert: func(t *testing.T, resp *http.Response) {
				require.Equal(t, http.StatusOK, resp.StatusCode)

				var limits map[string]struct {
					Max       int `json:"Max"`
					Remaining int `json:"Remaining"`
				}
				liveapi.DecodeJSON(t, resp, &limits)
				require.NotEmpty(t, limits)

				allocation, ok := limits["DailyApiRequests"]
				require.True(t, ok)
				assert.Greater(t, allocation.Max, 0)
				assert.GreaterOrEqual(t, allocation.Remaining, 0)
				assert.LessOrEqual(t, allocation.Remaining, allocation.Max)
			},
		},
	}

	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			path := tc.arrange(t)
			resp := tc.act(t, path)
			tc.assert(t, resp)
		})
	}
}
