Skip to content

Commit

Permalink
Storybook, tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mcbattirola committed Oct 30, 2024
1 parent 7d67d64 commit f278597
Show file tree
Hide file tree
Showing 5 changed files with 213 additions and 2 deletions.
53 changes: 53 additions & 0 deletions lib/web/apiserver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -11266,3 +11266,56 @@ func Test_setEntitlementsWithLegacyLogic(t *testing.T) {
})
}
}

// TestGetClusterInfo tests the getClusterInfo handler.
func TestGetClusterInfo(t *testing.T) {
tests := []struct {
name string
cloud bool
assert func(t *testing.T, err error, statusCode int, resp GetClusterInfoResponse)
}{
{
name: "cloud cluster",
cloud: true,
assert: func(t *testing.T, err error, statusCode int, resp GetClusterInfoResponse) {
require.NoError(t, err)
require.Equal(t, http.StatusOK, statusCode)
require.True(t, resp.IsCloud)
},
},
{
name: "non-cloud cluster",
cloud: false,
assert: func(t *testing.T, err error, statusCode int, resp GetClusterInfoResponse) {
require.NoError(t, err)
require.Equal(t, http.StatusOK, statusCode)
require.False(t, resp.IsCloud)
},
},
}

// Iterate over test cases.
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
modules.SetTestModules(t, &modules.TestModules{
TestFeatures: modules.Features{
Cloud: tc.cloud,
},
})

env := newWebPack(t, 1)
proxy := env.proxies[0]
pack := proxy.authPack(t, "[email protected]", auth.GetPresetRoles())
endpoint := pack.clt.Endpoint("webapi", "sites", env.server.ClusterName(), "info")

var clusterInfo GetClusterInfoResponse
resp, reqErr := pack.clt.Get(context.Background(), endpoint, url.Values{})
if reqErr != nil && resp.Code() == http.StatusOK {
err := json.Unmarshal(resp.Bytes(), &clusterInfo)
require.NoError(t, err)
}

tc.assert(t, reqErr, resp.Code(), clusterInfo)
})
}
}
4 changes: 2 additions & 2 deletions web/packages/teleport/src/Clusters/Clusters.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ import { FeaturesContextProvider } from 'teleport/FeaturesContext';

import { getOSSFeatures } from 'teleport/features';

import { Clusters } from './Clusters';
import { ClusterListPage } from './Clusters';
import * as fixtures from './fixtures';

export default {
Expand All @@ -40,7 +40,7 @@ export function Story({ value }: { value: teleport.Context }) {
<teleport.ContextProvider ctx={ctx}>
<FeaturesContextProvider value={getOSSFeatures()}>
<Router history={createMemoryHistory()}>
<Clusters />
<ClusterListPage />
</Router>
</FeaturesContextProvider>
</teleport.ContextProvider>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/**
* Teleport
* Copyright (C) 2024 Gravitational, Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import React from 'react';
import { MemoryRouter } from 'react-router';

import { createTeleportContext } from 'teleport/mocks/contexts';
import { ContextProvider } from 'teleport/index';
import { ContentMinWidth } from 'teleport/Main/Main';
import { Route } from 'teleport/components/Router';

import { clusterInfoFixture } from '../fixtures';

import { ManageCluster } from './ManageCluster';

export default {
title: 'Teleport/Clusters/ManageCluster',
};

function render(fetchClusterDetails: (clusterId: string) => Promise<any>) {
const ctx = createTeleportContext();

ctx.clusterService.fetchClusterDetails = fetchClusterDetails;
return (
<MemoryRouter initialEntries={['/clusters/test-cluster']}>
<Route path="/clusters/:clusterId">
<ContentMinWidth>
<ContextProvider ctx={ctx}>
<ManageCluster />
</ContextProvider>
</ContentMinWidth>
</Route>
</MemoryRouter>
);
}

export function Loading() {
const fetchClusterDetails = () => {
// promise never resolves to simulate loading state
return new Promise(() => {});
};
return render(fetchClusterDetails);
}

export function Failed() {
const fetchClusterDetails = () =>
Promise.reject(new Error('Failed to load cluster details'));
return render(fetchClusterDetails);
}

export function Success() {
const fetchClusterDetails = () => {
return new Promise(resolve => {
resolve(clusterInfoFixture);
});
};
return render(fetchClusterDetails);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import React from 'react';
import { MemoryRouter, Route } from 'react-router-dom';

import { render, waitFor, screen } from 'design/utils/testing';

import { ContextProvider } from 'teleport/index';
import { createTeleportContext } from 'teleport/mocks/contexts';
import { ContentMinWidth } from 'teleport/Main/Main';

import { clusterInfoFixture } from '../fixtures';

import { ManageCluster } from './ManageCluster';

function renderElement(element, ctx) {
return render(
<MemoryRouter initialEntries={[`/clusters/cluster-id`]}>
<Route path="/clusters/:clusterId">
<ContentMinWidth>
<ContextProvider ctx={ctx}>{element}</ContextProvider>
</ContentMinWidth>
</Route>
</MemoryRouter>
);
}

describe('test ManageCluster component', () => {
beforeEach(() => {
jest.resetAllMocks();
jest.spyOn(console, 'error').mockImplementation();
});

test('fetches cluster information on load', async () => {
const ctx = createTeleportContext();
jest
.spyOn(ctx.clusterService, 'fetchClusterDetails')
.mockResolvedValueOnce({ ...clusterInfoFixture });

renderElement(<ManageCluster />, ctx);
await waitFor(() => {
expect(
screen.getByText(clusterInfoFixture.authVersion)
).toBeInTheDocument();
});

expect(screen.getByText(clusterInfoFixture.clusterId)).toBeInTheDocument();
expect(screen.getByText(clusterInfoFixture.publicURL)).toBeInTheDocument();

expect(ctx.clusterService.fetchClusterDetails).toHaveBeenCalledTimes(1);
});

test('shows error when load fails', async () => {
const ctx = createTeleportContext();
jest
.spyOn(ctx.clusterService, 'fetchClusterDetails')
.mockRejectedValue({ message: 'error message' });

renderElement(<ManageCluster />, ctx);
await waitFor(() => {
expect(
screen.queryByText(clusterInfoFixture.authVersion)
).not.toBeInTheDocument();
});

await waitFor(() => {
expect(screen.getByText('error message')).toBeInTheDocument();
});

expect(ctx.clusterService.fetchClusterDetails).toHaveBeenCalledTimes(1);
});
});
15 changes: 15 additions & 0 deletions web/packages/teleport/src/Clusters/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

import { ClusterInfo } from "teleport/services/clusters";

export const clusters = [
{
clusterId: 'localhost',
Expand Down Expand Up @@ -428,3 +430,16 @@ export const clusters = [
proxyVersion: '1.14.3',
},
];

export const clusterInfoFixture: ClusterInfo = {
authVersion: 'v17.0.0',
clusterId: 'cluster-id',
connectedText: '',
isCloud: false,
lastConnected: new Date(),
proxyVersion: 'v17.0.0',
publicURL: 'example.teleport.com',
status: 'active',
url: 'example.teleport.com',
licenseExpiryDateText: new Date().toISOString(),
};

0 comments on commit f278597

Please sign in to comment.