|
| 1 | +import { grpc } from "@improbable-eng/grpc-web"; |
1 | 2 | import Axios, { AxiosResponse } from "axios"; |
| 3 | +import { CheckNamespaceExistsRequest } from "gen/kubeappsapis/plugins/resources/v1alpha1/resources"; |
2 | 4 | import * as jwt from "jsonwebtoken"; |
3 | 5 | import { Auth } from "./Auth"; |
4 | 6 | import { SupportedThemes } from "./Config"; |
| 7 | +import { KubeappsGrpcClient } from "./KubeappsGrpcClient"; |
5 | 8 |
|
6 | 9 | describe("Auth", () => { |
| 10 | + // Create a real client, but we'll stub out the function we're interested in. |
| 11 | + const client = new KubeappsGrpcClient().getResourcesServiceClientImpl(); |
| 12 | + let mockClientCheckNamespaceExists: jest.MockedFunction<typeof client.CheckNamespaceExists>; |
| 13 | + |
7 | 14 | beforeEach(() => { |
8 | 15 | Axios.get = jest.fn(); |
| 16 | + mockClientCheckNamespaceExists = jest |
| 17 | + .fn() |
| 18 | + .mockImplementation(() => Promise.resolve({ exists: true } as CheckNamespaceExistsRequest)); |
| 19 | + jest.spyOn(client, "CheckNamespaceExists").mockImplementation(mockClientCheckNamespaceExists); |
| 20 | + jest.spyOn(Auth, "resourcesClient").mockImplementation(() => client); |
9 | 21 | }); |
10 | 22 | afterEach(() => { |
11 | 23 | jest.resetAllMocks(); |
12 | 24 | }); |
13 | | - it("should get an URL with the given token", async () => { |
14 | | - const mock = jest.fn(); |
15 | | - Axios.get = mock; |
| 25 | + |
| 26 | + it("should return without error when the endpoint succeeds with the given token", async () => { |
16 | 27 | await Auth.validateToken("othercluster", "foo"); |
17 | | - expect(mock.mock.calls[0]).toEqual([ |
18 | | - "api/clusters/othercluster/", |
19 | | - { headers: { Authorization: "Bearer foo" } }, |
20 | | - ]); |
| 28 | + |
| 29 | + expect(Auth.resourcesClient).toHaveBeenCalledWith("foo"); |
| 30 | + expect(mockClientCheckNamespaceExists).toHaveBeenCalledWith({ |
| 31 | + context: { |
| 32 | + cluster: "othercluster", |
| 33 | + namespace: "default", |
| 34 | + }, |
| 35 | + }); |
| 36 | + }); |
| 37 | + |
| 38 | + it("should return without error when the endpoint returns PermissionDenied with the given token", async () => { |
| 39 | + mockClientCheckNamespaceExists = jest |
| 40 | + .fn() |
| 41 | + .mockImplementation(() => Promise.reject({ code: grpc.Code.PermissionDenied })); |
| 42 | + jest.spyOn(client, "CheckNamespaceExists").mockImplementation(mockClientCheckNamespaceExists); |
| 43 | + await Auth.validateToken("othercluster", "foo"); |
| 44 | + |
| 45 | + expect(Auth.resourcesClient).toHaveBeenCalledWith("foo"); |
| 46 | + expect(mockClientCheckNamespaceExists).toHaveBeenCalledWith({ |
| 47 | + context: { |
| 48 | + cluster: "othercluster", |
| 49 | + namespace: "default", |
| 50 | + }, |
| 51 | + }); |
21 | 52 | }); |
22 | 53 |
|
23 | 54 | describe("when there is an error", () => { |
24 | 55 | [ |
25 | 56 | { |
26 | 57 | name: "should throw an invalid token error for 401 responses", |
27 | 58 | response: { status: 401, data: "ignored anyway" }, |
| 59 | + grpcCode: grpc.Code.Unauthenticated, |
28 | 60 | expectedError: new Error("invalid token"), |
29 | 61 | }, |
30 | 62 | { |
31 | 63 | name: "should throw a standard error for a 404 response", |
32 | | - response: { status: 404, data: "Not found" }, |
33 | | - expectedError: new Error("404: Not found"), |
| 64 | + grpcCode: grpc.Code.NotFound, |
| 65 | + expectedError: new Error("not found"), |
34 | 66 | }, |
35 | 67 | { |
36 | 68 | name: "should throw a standard error for a 500 response", |
37 | | - response: { status: 500, data: "Server exception" }, |
38 | | - expectedError: new Error("500: Server exception"), |
39 | | - }, |
40 | | - { |
41 | | - name: "should succeed for a 403 response", |
42 | | - response: { status: 403, data: "Not Allowed" }, |
43 | | - expectedError: null, |
| 69 | + grpcCode: grpc.Code.Internal, |
| 70 | + expectedError: new Error("internal error"), |
44 | 71 | }, |
45 | 72 | ].forEach(testCase => { |
46 | 73 | it(testCase.name, async () => { |
47 | | - const mock = jest.fn(() => { |
48 | | - return Promise.reject({ response: testCase.response }); |
49 | | - }); |
50 | | - Axios.get = mock; |
51 | | - // TODO(absoludity): tried using `expect(fn()).rejects.toThrow()` but it seems we need |
52 | | - // to upgrade jest for `toThrow()` to work with async. |
53 | | - let err = null; |
54 | | - try { |
55 | | - await Auth.validateToken("default", "foo"); |
56 | | - } catch (e: any) { |
57 | | - err = e; |
58 | | - } finally { |
59 | | - expect(err).toEqual(testCase.expectedError); |
60 | | - } |
| 74 | + mockClientCheckNamespaceExists = jest |
| 75 | + .fn() |
| 76 | + .mockImplementation(() => Promise.reject({ code: testCase.grpcCode })); |
| 77 | + jest |
| 78 | + .spyOn(client, "CheckNamespaceExists") |
| 79 | + .mockImplementation(mockClientCheckNamespaceExists); |
| 80 | + |
| 81 | + await expect(Auth.validateToken("default", "foo")).rejects.toThrow(testCase.expectedError); |
61 | 82 | }); |
62 | 83 | }); |
63 | 84 | }); |
|
0 commit comments