Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

docs: add public Git error messages #1283

Merged
merged 20 commits into from
Feb 6, 2024
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
test: add initial tests
angeloashmore committed Jan 18, 2024
commit 7904dd34fc69b1f0d7a224dd609b998092bce801
2 changes: 1 addition & 1 deletion packages/manager/package.json
Original file line number Diff line number Diff line change
@@ -110,7 +110,7 @@
"eslint-config-prettier": "9.0.0",
"eslint-plugin-prettier": "5.0.1",
"eslint-plugin-tsdoc": "0.2.17",
"express": "4.18.2",
"express": "^1.0.0",
"hook-std": "3.0.0",
"memfs": "3.4.13",
"msw": "1.1.0",
60 changes: 32 additions & 28 deletions packages/manager/src/managers/git/GitManager.ts
Original file line number Diff line number Diff line change
@@ -22,7 +22,7 @@ type GitManagerFetchOwnersReturnType = Namespace[];
type GitManagerFetchReposReturnType = GitRepo[];

type GitManagerFetchReposArgs = {
platform: "gitHub";
provider: "gitHub";
owner: string;
query?: string;
page?: number;
@@ -109,14 +109,16 @@ export class GitManager extends BaseManager {

const json = await res.json();
const { value, error } = decode(
t.array(
t.type({
platform: t.literal("gitHub"),
id: t.string,
name: t.string,
type: t.union([t.literal("user"), t.literal("team"), t.null]),
}),
),
t.type({
owners: t.array(
t.type({
provider: t.literal("gitHub"),
id: t.string,
name: t.string,
type: t.union([t.literal("user"), t.literal("team"), t.null]),
}),
),
}),
json,
);

@@ -127,14 +129,14 @@ export class GitManager extends BaseManager {
);
}

return value;
return value.owners;
}

async fetchRepos(
args: GitManagerFetchReposArgs,
): Promise<GitManagerFetchReposReturnType> {
const url = new URL("./git/repos", API_ENDPOINTS.SliceMachineV1);
url.searchParams.set("platform", args.platform);
url.searchParams.set("provider", args.provider);
url.searchParams.set("owner", args.owner);
if (args.query) {
url.searchParams.set("q", args.query);
@@ -156,16 +158,18 @@ export class GitManager extends BaseManager {

const json = await res.json();
const { value, error } = decode(
t.array(
t.type({
platform: t.literal("gitHub"),
id: t.string,
owner: t.string,
name: t.string,
url: t.string,
pushedAt: tt.DateFromISOString,
}),
),
t.type({
repos: t.array(
t.type({
provider: t.literal("gitHub"),
id: t.string,
owner: t.string,
name: t.string,
url: t.string,
pushedAt: tt.DateFromISOString,
}),
),
}),
json,
);

@@ -176,7 +180,7 @@ export class GitManager extends BaseManager {
);
}

return value;
return value.repos;
}

async fetchLinkedRepos(
@@ -199,7 +203,7 @@ export class GitManager extends BaseManager {
const json = await res.json();
const { value, error } = decode(
t.type({
gitHubRepos: t.array(
repos: t.array(
t.type({
provider: t.literal("gitHub"),
owner: t.string,
@@ -217,14 +221,14 @@ export class GitManager extends BaseManager {
);
}

return value.gitHubRepos;
return value.repos;
}

async linkRepo(args: GitManagerLinkRepoArgs): Promise<void> {
const url = new URL("./git/linked-repos", API_ENDPOINTS.SliceMachineV1);
const res = await this.#fetch(url, {
method: "PUT",
body: JSON.stringify({
body: {
prismic: {
domain: args.prismic.domain,
},
@@ -233,7 +237,7 @@ export class GitManager extends BaseManager {
owner: args.git.owner,
name: args.git.name,
},
}),
},
});

if (!res.ok) {
@@ -250,7 +254,7 @@ export class GitManager extends BaseManager {
const url = new URL("./git/linked-repos", API_ENDPOINTS.SliceMachineV1);
const res = await this.#fetch(url, {
method: "DELETE",
body: JSON.stringify({
body: {
prismic: {
domain: args.prismic.domain,
},
@@ -259,7 +263,7 @@ export class GitManager extends BaseManager {
owner: args.git.owner,
name: args.git.name,
},
}),
},
});

if (!res.ok) {
Original file line number Diff line number Diff line change
@@ -454,10 +454,7 @@ export class PrismicRepositoryManager extends BaseManager {
): Promise<PrismicRepositoryManagerFetchEnvironmentsReturnType> {
const repositoryName = await this.project.getRepositoryName();

const url = new URL(
`./environments`,
API_ENDPOINTS.SliceMachineEnvironmentsV1,
);
const url = new URL(`./environments`, API_ENDPOINTS.SliceMachineV1);
url.searchParams.set("repository", repositoryName);

const res = await this._fetch({ url });
3 changes: 3 additions & 0 deletions packages/manager/test/PrismicAuthManager-login.test.ts
Original file line number Diff line number Diff line change
@@ -32,6 +32,9 @@ it("retains existing cookies in the auth state file", async (ctx) => {

mockPrismicUserAPI(ctx);

// Clear all cookies
await prismicAuthManager.logout();

await prismicAuthManager.login({
email: "name@example.com",
cookies: ["foo=bar"],
1 change: 1 addition & 0 deletions packages/manager/test/SliceMachineManager-getState.test.ts
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@ it("returns global Slice Machine state", async () => {
},
});
await manager.plugins.initPlugins();
await manager.user.logout();
const result = await manager.getState();

expect(result.env.endpoints).toStrictEqual({
Original file line number Diff line number Diff line change
@@ -1,66 +1,41 @@
import { expect, it } from "vitest";

import { createPrismicAuthLoginResponse } from "./__testutils__/createPrismicAuthLoginResponse";
import { createTestPlugin } from "./__testutils__/createTestPlugin";
import { createTestProject } from "./__testutils__/createTestProject";
import { mockPrismicAuthAPI } from "./__testutils__/mockPrismicAuthAPI";
import { mockPrismicUserAPI } from "./__testutils__/mockPrismicUserAPI";
import { UnauthenticatedError, UnauthorizedError } from "../src";

import { createSliceMachineManager, SliceMachineManager } from "../src";
import { rest, RestRequest } from "msw";

it("returns a GitHub auth state token", async (ctx) => {
const adapter = createTestPlugin();
const cwd = await createTestProject({ adapter });
const manager = createSliceMachineManager({
nativePlugins: { [adapter.meta.name]: adapter },
cwd,
});

await manager.plugins.initPlugins();

mockPrismicUserAPI(ctx);
mockPrismicAuthAPI(ctx);

await manager.user.login(createPrismicAuthLoginResponse());

const authenticationToken = await manager.user.getAuthenticationToken();
it("returns a GitHub auth state token", async ({ manager, api }) => {
const key = "foo";
const expiresAt = new Date(Date.now() + 1000 * 60 * 5);
const expiresAt = new Date();

const checkAuthorizationToken = (
req: RestRequest,
authenticationToken: string,
): boolean => {
return req.headers.get("Authorization") === `Bearer ${authenticationToken}`;
};
api.mockSliceMachineV1(
"./git/github/create-auth-state",
{ key, expiresAt: expiresAt.toISOString() },
{ checkAuthentication: true },
);

const res = await manager.git.createGitHubAuthState();

const buildURL = (endpoint: string, manager: SliceMachineManager): string => {
return new URL(
endpoint,
manager.getAPIEndpoints().SliceMachineV1,
).toString();
};
expect(res).toStrictEqual({ key, expiresAt });
});

ctx.msw.use(
rest.get(
buildURL("./git/github/create-auth-state", manager),
(req, res, ctx) => {
if (!checkAuthorizationToken(req, authenticationToken)) {
return;
}
it("throws UnauthorizedError if the API returns 401", async ({
manager,
api,
}) => {
api.mockSliceMachineV1("./git/github/create-auth-state", undefined, {
statusCode: 401,
});

return res(
ctx.json({
key,
expiresAt: expiresAt.toISOString(),
}),
);
},
),
await expect(() => manager.git.createGitHubAuthState()).rejects.toThrow(
UnauthorizedError,
);
});

const result = await manager.git.createGitHubAuthState();
it("throws UnauthenticatedError if the user is logged out", async ({
manager,
}) => {
await manager.user.logout();

expect(result).toStrictEqual({ key, expiresAt });
await expect(() => manager.git.createGitHubAuthState()).rejects.toThrow(
UnauthenticatedError,
);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, it } from "vitest";
import { UnauthenticatedError, UnauthorizedError } from "../src";

it("returns a list of linked repos for a repo", async ({ manager, api }) => {
const domain = "domain";
const repos = [{ provider: "gitHub", owner: "owner", name: "name" }];

api.mockSliceMachineV1(
"./git/linked-repos",
{ repos },
{ searchParams: { repository: domain } },
);

const res = await manager.git.fetchLinkedRepos({ prismic: { domain } });

expect(res).toStrictEqual(repos);
});

it("throws UnauthorizedError if the API returns 403", async ({
manager,
api,
}) => {
api.mockSliceMachineV1("./git/linked-repos", undefined, { statusCode: 403 });

await expect(() =>
manager.git.fetchLinkedRepos({ prismic: { domain: "domain" } }),
).rejects.toThrow(UnauthorizedError);
});

it("throws UnauthenticatedError if the user is logged out", async ({
manager,
}) => {
await manager.user.logout();

await expect(() =>
manager.git.fetchLinkedRepos({ prismic: { domain: "domain" } }),
).rejects.toThrow(UnauthenticatedError);
});
34 changes: 34 additions & 0 deletions packages/manager/test/SliceMachineManager-git-fetchOwners.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { expect, it } from "vitest";

import { UnauthenticatedError, UnauthorizedError } from "../src";

it("returns a list of owners for the user", async ({ manager, api }) => {
const owners = [{ provider: "gitHub", id: "id", name: "name", type: "user" }];

api.mockSliceMachineV1("./git/owners", { owners });

const res = await manager.git.fetchOwners();

expect(res).toStrictEqual(owners);
});

it("throws UnauthorizedError if the API returns 403", async ({
manager,
api,
}) => {
api.mockSliceMachineV1("./git/owners", undefined, { statusCode: 403 });

await expect(() => manager.git.fetchOwners()).rejects.toThrow(
UnauthorizedError,
);
});

it("throws UnauthenticatedError if the user is logged out", async ({
manager,
}) => {
await manager.user.logout();

await expect(() => manager.git.fetchOwners()).rejects.toThrow(
UnauthenticatedError,
);
});
Loading