1package tfe
2
3import (
4	"context"
5	"testing"
6	"time"
7
8	"github.com/stretchr/testify/assert"
9	"github.com/stretchr/testify/require"
10)
11
12func TestConfigurationVersionsList(t *testing.T) {
13	client := testClient(t)
14	ctx := context.Background()
15
16	wTest, wTestCleanup := createWorkspace(t, client, nil)
17	defer wTestCleanup()
18
19	cvTest1, cvTest1Cleanup := createConfigurationVersion(t, client, wTest)
20	defer cvTest1Cleanup()
21	cvTest2, cvTest2Cleanup := createConfigurationVersion(t, client, wTest)
22	defer cvTest2Cleanup()
23
24	t.Run("without list options", func(t *testing.T) {
25		options := ConfigurationVersionListOptions{}
26
27		cvl, err := client.ConfigurationVersions.List(ctx, wTest.ID, options)
28		require.NoError(t, err)
29
30		// We need to strip the upload URL as that is a dynamic link.
31		cvTest1.UploadURL = ""
32		cvTest2.UploadURL = ""
33
34		// And for the retrieved configuration versions as well.
35		for _, cv := range cvl.Items {
36			cv.UploadURL = ""
37		}
38
39		assert.Contains(t, cvl.Items, cvTest1)
40		assert.Contains(t, cvl.Items, cvTest2)
41		assert.Equal(t, 1, cvl.CurrentPage)
42		assert.Equal(t, 2, cvl.TotalCount)
43	})
44
45	t.Run("with list options", func(t *testing.T) {
46		// Request a page number which is out of range. The result should
47		// be successful, but return no results if the paging options are
48		// properly passed along.
49		options := ConfigurationVersionListOptions{
50			ListOptions: ListOptions{
51				PageNumber: 999,
52				PageSize:   100,
53			},
54		}
55
56		cvl, err := client.ConfigurationVersions.List(ctx, wTest.ID, options)
57		require.NoError(t, err)
58		assert.Empty(t, cvl.Items)
59		assert.Equal(t, 999, cvl.CurrentPage)
60		assert.Equal(t, 2, cvl.TotalCount)
61	})
62
63	t.Run("without a valid organization", func(t *testing.T) {
64		options := ConfigurationVersionListOptions{}
65
66		cvl, err := client.ConfigurationVersions.List(ctx, badIdentifier, options)
67		assert.Nil(t, cvl)
68		assert.EqualError(t, err, "invalid value for workspace ID")
69	})
70}
71
72func TestConfigurationVersionsCreate(t *testing.T) {
73	client := testClient(t)
74	ctx := context.Background()
75
76	wTest, wTestCleanup := createWorkspace(t, client, nil)
77	defer wTestCleanup()
78
79	t.Run("with valid options", func(t *testing.T) {
80		cv, err := client.ConfigurationVersions.Create(ctx,
81			wTest.ID,
82			ConfigurationVersionCreateOptions{},
83		)
84		require.NoError(t, err)
85
86		// Get a refreshed view of the configuration version.
87		refreshed, err := client.ConfigurationVersions.Read(ctx, cv.ID)
88		require.NoError(t, err)
89
90		for _, item := range []*ConfigurationVersion{
91			cv,
92			refreshed,
93		} {
94			assert.NotEmpty(t, item.ID)
95			assert.Empty(t, item.Error)
96			assert.Equal(t, item.Source, ConfigurationSourceAPI)
97			assert.Equal(t, item.Status, ConfigurationPending)
98			assert.NotEmpty(t, item.UploadURL)
99		}
100	})
101
102	t.Run("with invalid workspace id", func(t *testing.T) {
103		cv, err := client.ConfigurationVersions.Create(
104			ctx,
105			badIdentifier,
106			ConfigurationVersionCreateOptions{},
107		)
108		assert.Nil(t, cv)
109		assert.EqualError(t, err, "invalid value for workspace ID")
110	})
111}
112
113func TestConfigurationVersionsRead(t *testing.T) {
114	client := testClient(t)
115	ctx := context.Background()
116
117	cvTest, cvTestCleanup := createConfigurationVersion(t, client, nil)
118	defer cvTestCleanup()
119
120	t.Run("when the configuration version exists", func(t *testing.T) {
121		cv, err := client.ConfigurationVersions.Read(ctx, cvTest.ID)
122		require.NoError(t, err)
123
124		// Don't compare the UploadURL because it will be generated twice in
125		// this test - once at creation of the configuration version, and
126		// again during the GET.
127		cvTest.UploadURL, cv.UploadURL = "", ""
128
129		assert.Equal(t, cvTest, cv)
130	})
131
132	t.Run("when the configuration version does not exist", func(t *testing.T) {
133		cv, err := client.ConfigurationVersions.Read(ctx, "nonexisting")
134		assert.Nil(t, cv)
135		assert.Equal(t, err, ErrResourceNotFound)
136	})
137
138	t.Run("with invalid configuration version id", func(t *testing.T) {
139		cv, err := client.ConfigurationVersions.Read(ctx, badIdentifier)
140		assert.Nil(t, cv)
141		assert.EqualError(t, err, "invalid value for configuration version ID")
142	})
143}
144
145func TestConfigurationVersionsUpload(t *testing.T) {
146	client := testClient(t)
147	ctx := context.Background()
148
149	cv, cvCleanup := createConfigurationVersion(t, client, nil)
150	defer cvCleanup()
151
152	t.Run("with valid options", func(t *testing.T) {
153		err := client.ConfigurationVersions.Upload(
154			ctx,
155			cv.UploadURL,
156			"test-fixtures/config-version",
157		)
158		require.NoError(t, err)
159
160		// We do this is a small loop, because it can take a second
161		// before the upload is finished.
162		for i := 0; ; i++ {
163			refreshed, err := client.ConfigurationVersions.Read(ctx, cv.ID)
164			require.NoError(t, err)
165
166			if refreshed.Status == ConfigurationUploaded {
167				break
168			}
169
170			if i > 10 {
171				t.Fatal("Timeout waiting for the configuration version to be uploaded")
172			}
173
174			time.Sleep(1 * time.Second)
175		}
176	})
177
178	t.Run("without a valid upload URL", func(t *testing.T) {
179		err := client.ConfigurationVersions.Upload(
180			ctx,
181			cv.UploadURL[:len(cv.UploadURL)-10]+"nonexisting",
182			"test-fixtures/config-version",
183		)
184		assert.Error(t, err)
185	})
186
187	t.Run("without a valid path", func(t *testing.T) {
188		err := client.ConfigurationVersions.Upload(
189			ctx,
190			cv.UploadURL,
191			"nonexisting",
192		)
193		assert.Error(t, err)
194	})
195}
196