Skip to content

Commit

Permalink
feat(misc): prioritize github onboarding flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mandarini committed Jul 24, 2024
1 parent 232e124 commit 57245c5
Show file tree
Hide file tree
Showing 6 changed files with 376 additions and 65 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { readNxJson } from '../../config/configuration';
import { FsTree, flushChanges } from '../../generators/tree';
import { connectToNxCloud } from '../../nx-cloud/generators/connect-to-nx-cloud/connect-to-nx-cloud';
import { shortenedCloudUrl } from '../../nx-cloud/utilities/url-shorten';
import { getNxCloudUrl, isNxCloudUsed } from '../../utils/nx-cloud-utils';
import { isNxCloudUsed } from '../../utils/nx-cloud-utils';
import { runNxSync } from '../../utils/child-process';
import { NxJsonConfiguration } from '../../config/nx-json';
import { NxArgs } from '../../utils/command-line-utils';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,9 @@ async function createNxCloudWorkspace(
}

async function printSuccessMessage(
url: string,
token: string | undefined,
installationSource: string,
usesGithub?: boolean,
usesGithub: boolean,
directory?: string
) {
const connectCloudUrl = await shortenedCloudUrl(
Expand Down Expand Up @@ -205,10 +204,8 @@ export async function connectToNxCloud(
silent: schema.hideFormatLogs,
});
}
const apiUrl = getCloudUrl();
return async () =>
await printSuccessMessage(
responseFromCreateNxCloudWorkspace?.url ?? apiUrl,
responseFromCreateNxCloudWorkspace?.token,
schema.installationSource,
usesGithub,
Expand Down
155 changes: 155 additions & 0 deletions packages/nx/src/nx-cloud/utilities/url-shorten.spec.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,26 @@
import { getGithubSlugOrNull } from '../../utils/git-utils';
import {
removeVersionModifier,
compareCleanCloudVersions,
getNxCloudVersion,
versionIsValid,
getURLifShortenFailed,
repoUsesGithub,
} from './url-shorten';
import { getCloudUrl } from './get-cloud-options';

jest.mock('axios', () => ({
get: jest.fn(),
}));

jest.mock('../../utils/git-utils', () => ({
getGithubSlugOrNull: jest.fn(),
}));

jest.mock('./get-cloud-options', () => ({
getCloudUrl: jest.fn(),
}));

describe('URL shorten various functions', () => {
describe('compareCleanCloudVersions', () => {
it('should return 1 if the first version is newer', () => {
Expand Down Expand Up @@ -100,4 +112,147 @@ describe('URL shorten various functions', () => {
expect(versionIsValid('2312.26.extra')).toBe(false); // Non-numeric build number
});
});

describe('getURLifShortenFailed', () => {
const apiUrl = 'https://example.com';
const source = 'source-test';
const accessToken = 'access-token';

test('should return GitHub URL with slug when usesGithub is true and githubSlug is provided', () => {
const usesGithub = true;
const githubSlug = 'user/repo';

const result = getURLifShortenFailed(
usesGithub,
githubSlug,
apiUrl,
source
);

expect(result).toBe(
`${apiUrl}/setup/connect-workspace/github/connect?name=${encodeURIComponent(
githubSlug
)}&source=${source}`
);
});

test('should return GitHub select URL when usesGithub is true and githubSlug is not provided', () => {
const usesGithub = true;
const githubSlug = null;

const result = getURLifShortenFailed(
usesGithub,
githubSlug,
apiUrl,
source
);

expect(result).toBe(
`${apiUrl}/setup/connect-workspace/github/select&source=${source}`
);
});

test('should return manual URL when usesGithub is false', () => {
const usesGithub = false;
const githubSlug = 'user/repo';

const result = getURLifShortenFailed(
usesGithub,
githubSlug,
apiUrl,
source,
accessToken
);

expect(result).toBe(
`${apiUrl}/setup/connect-workspace/manual?accessToken=${accessToken}&source=${source}`
);
});

test('should return manual URL when usesGithub is false and accessToken is not provided', () => {
const usesGithub = false;
const githubSlug = null;

const result = getURLifShortenFailed(
usesGithub,
githubSlug,
apiUrl,
source
);

expect(result).toBe(
`${apiUrl}/setup/connect-workspace/manual?accessToken=undefined&source=${source}`
);
});
});

describe('repoUsesGithub', () => {
const axios = require('axios');
beforeEach(() => {
jest.resetAllMocks();
});

it('should return true when githubSlug is provided and apiUrl includes cloud.nx.app', async () => {
(getGithubSlugOrNull as jest.Mock).mockReturnValue('user/repo');
(getCloudUrl as jest.Mock).mockReturnValue('https://cloud.nx.app');
axios.get.mockResolvedValue({
data: { isGithubIntegrationEnabled: false },
});
const result = await repoUsesGithub(
false,
'user/repo',
'https://cloud.nx.app'
);

expect(result).toBe(true);
});

it('should return true when github is true and installation supports GitHub', async () => {
(getGithubSlugOrNull as jest.Mock).mockReturnValue(null);
(getCloudUrl as jest.Mock).mockReturnValue('https://api.other.app');
axios.get.mockResolvedValue({
data: { isGithubIntegrationEnabled: true },
});
const result = await repoUsesGithub(
true,
undefined,
'https://api.other.app'
);

expect(result).toBe(true);
});

it('should return false when githubSlug and github are not provided and installation does not support GitHub', async () => {
(getGithubSlugOrNull as jest.Mock).mockReturnValue(null);
(getCloudUrl as jest.Mock).mockReturnValue('https://api.other.app');
axios.get.mockResolvedValue({
data: { isGithubIntegrationEnabled: false },
});
const result = await repoUsesGithub();
expect(result).toBe(false);
});

it('should return true when githubSlug is not provided but github is true and apiUrl includes eu.nx.app', async () => {
(getGithubSlugOrNull as jest.Mock).mockReturnValue(null);
(getCloudUrl as jest.Mock).mockReturnValue('https://eu.nx.app');
axios.get.mockResolvedValue({
data: { isGithubIntegrationEnabled: false },
});
const result = await repoUsesGithub(true, undefined, 'https://eu.nx.app');

expect(result).toBe(true);
});

it('should return true when apiUrl is not provided but githubSlug is provided and installation supports GitHub', async () => {
(getGithubSlugOrNull as jest.Mock).mockReturnValue('user/repo');
(getCloudUrl as jest.Mock).mockReturnValue('https://api.other.app');
axios.get.mockResolvedValue({
data: { isGithubIntegrationEnabled: true },
});
const result = await repoUsesGithub(false, 'user/repo');

expect(result).toBe(true);
expect(getCloudUrl).toHaveBeenCalled();
});
});
});
28 changes: 19 additions & 9 deletions packages/nx/src/nx-cloud/utilities/url-shorten.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ export async function shortenedCloudUrl(

const apiUrl = getCloudUrl();

if (usesGithub === undefined || usesGithub === null) {
usesGithub = await repoUsesGithub(undefined, githubSlug, apiUrl);
}

try {
const version = await getNxCloudVersion(apiUrl);
if (
Expand All @@ -34,7 +38,7 @@ export async function shortenedCloudUrl(
type: usesGithub ? 'GITHUB' : 'MANUAL',
source,
accessToken: usesGithub ? null : accessToken,
selectedRepositoryName: githubSlug,
selectedRepositoryName: githubSlug === 'github' ? null : githubSlug,
}
);

Expand All @@ -50,25 +54,31 @@ export async function shortenedCloudUrl(
${e}`);
return getURLifShortenFailed(
usesGithub,
githubSlug,
githubSlug === 'github' ? null : githubSlug,
apiUrl,
source,
accessToken
);
}
}

export async function repoUsesGithub(github?: boolean) {
const githubSlug = getGithubSlugOrNull();

const apiUrl = getCloudUrl();

export async function repoUsesGithub(
github?: boolean,
githubSlug?: string,
apiUrl?: string
): Promise<boolean> {
if (!apiUrl) {
apiUrl = getCloudUrl();
}
if (!githubSlug) {
githubSlug = getGithubSlugOrNull();
}
const installationSupportsGitHub = await getInstallationSupportsGitHub(
apiUrl
);

return (
(githubSlug || github) &&
(!!githubSlug || !!github) &&
(apiUrl.includes('cloud.nx.app') ||
apiUrl.includes('eu.nx.app') ||
installationSupportsGitHub)
Expand All @@ -91,7 +101,7 @@ function getSource(

export function getURLifShortenFailed(
usesGithub: boolean,
githubSlug: string,
githubSlug: string | null,
apiUrl: string,
source: string,
accessToken?: string
Expand Down
Loading

0 comments on commit 57245c5

Please sign in to comment.