Merge pull request #23083 from acierto/scaffolder-test-utils

Introduced createMockActionContext to unify the way of creating scaffolder mock context in tests
This commit is contained in:
Ben Lambert
2024-02-27 13:20:25 +01:00
committed by GitHub
94 changed files with 647 additions and 980 deletions
+21
View File
@@ -0,0 +1,21 @@
---
'@backstage/plugin-scaffolder-backend-module-confluence-to-markdown': patch
'@backstage/plugin-scaffolder-backend-module-bitbucket-server': patch
'@backstage/plugin-scaffolder-backend-module-bitbucket-cloud': patch
'@backstage/plugin-scaffolder-backend-module-cookiecutter': patch
'@backstage/plugin-scaffolder-backend-module-bitbucket': patch
'@backstage/plugin-scaffolder-backend-module-gerrit': patch
'@backstage/plugin-scaffolder-backend-module-github': patch
'@backstage/plugin-scaffolder-backend-module-gitlab': patch
'@backstage/plugin-scaffolder-backend-module-sentry': patch
'@backstage/plugin-scaffolder-backend-module-yeoman': patch
'@backstage/plugin-scaffolder-backend-module-azure': patch
'@backstage/plugin-scaffolder-backend-module-gitea': patch
'@backstage/plugin-scaffolder-backend-module-rails': patch
'@backstage/plugin-scaffolder-node-test-utils': minor
'@backstage/plugin-scaffolder-backend': patch
---
Introduced `createMockActionContext` to unify the way of creating scaffolder mock context.
It will help to maintain tests in a long run during structural changes of action context.
@@ -0,0 +1,57 @@
---
id: writing-tests-for-actions
title: Writing Tests For Actions
description: How to write tests for actions
---
Once you created a new action, your own custom one, or you would like to contribute new actions, you have to cover it with
Unit tests to be sure that your actions do what they suppose to do.
Make sure that you cover the most of scenario's, which could happen with the action.
One of indispensable part of the test is to supply the context to a handler of action for the execution.
We encourage you to use a utility method for that, so your tests are immune to structural changes of context.
What is inevitably going to happen during the time.
Example how to use it:
```typescript
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
const mockContext = createMockActionContext({
input: { repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org' },
});
await action.handler(mockContext);
expect(mockContext.output).toHaveBeenCalledWith(
'remoteUrl',
'https://dev.azure.com/organization/project/_git/repo',
);
```
One thing to be aware about: if you would like to call `createMockActionContext` inside `it`,
you have to provide a `workspacePath`. By default, `createMockActionContext` uses
`import { createMockDirectory } from '@backstage/backend-test-utils';` to create it for you.
This implementation contains a hook inside which creates this limitation. So in this case you can do then:
```typescript
describe('github:autolinks:create', async () => {
const workspacePath = createMockDirectory().resolve('workspace');
// ...
it('should call the githubApis for creating alphanumeric autolink reference', async () => {
// ...
await action.handler(
createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
keyPrefix: 'TICKET-',
urlTemplate: 'https://example.com/TICKET?query=<num>',
},
workspacePath,
}),
);
//...
});
});
```
+1
View File
@@ -116,6 +116,7 @@
"features/software-templates/input-examples",
"features/software-templates/builtin-actions",
"features/software-templates/writing-custom-actions",
"features/software-templates/writing-tests-for-actions",
"features/software-templates/writing-custom-field-extensions",
"features/software-templates/writing-custom-step-layouts",
"features/software-templates/authorizing-parameters-steps-and-actions",
@@ -47,7 +47,8 @@
"yaml": "^2.0.0"
},
"devDependencies": {
"@backstage/cli": "workspace:^"
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
},
"files": [
"dist"
@@ -18,11 +18,10 @@ import yaml from 'yaml';
import { ConfigReader } from '@backstage/config';
import { createPublishAzureAction } from './azure';
import { ScmIntegrations } from '@backstage/integration';
import { getVoidLogger } from '@backstage/backend-common';
import { WebApi } from 'azure-devops-node-api';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { examples } from './azure.examples';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
jest.mock('azure-devops-node-api', () => ({
WebApi: jest.fn(),
@@ -55,13 +54,7 @@ describe('publish:azure examples', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishAzureAction({ integrations, config });
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
const mockGitClient = {
createRepository: jest.fn(),
@@ -34,10 +34,9 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
import { createPublishAzureAction } from './azure';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { WebApi } from 'azure-devops-node-api';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:azure', () => {
const config = new ConfigReader({
@@ -54,16 +53,10 @@ describe('publish:azure', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishAzureAction({ integrations, config });
const mockContext = {
input: {
repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext({
input: { repoUrl: 'dev.azure.com?repo=repo&owner=owner&organization=org' },
});
const mockGitClient = {
createRepository: jest.fn(),
@@ -50,6 +50,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -32,9 +32,8 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:bitbucketCloud', () => {
const config = new ConfigReader({
@@ -50,17 +49,12 @@ describe('publish:bitbucketCloud', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishBitbucketCloudAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo',
repoVisibility: 'private' as const,
},
workspacePath: 'wsp',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -14,16 +14,15 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { PassThrough } from 'stream';
import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun';
import yaml from 'yaml';
import { examples } from './bitbucketCloudPipelinesRun.examples';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('bitbucket:pipelines:run', () => {
const config = new ConfigReader({
@@ -39,14 +38,7 @@ describe('bitbucket:pipelines:run', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createBitbucketPipelinesRunAction({ integrations });
const mockContext = {
input: {},
workspacePath: 'wsp',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
const responseJson = {
repository: {
links: {
@@ -14,14 +14,13 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { PassThrough } from 'stream';
import { createBitbucketPipelinesRunAction } from './bitbucketCloudPipelinesRun';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('bitbucket:pipelines:run', () => {
const config = new ConfigReader({
@@ -37,14 +36,7 @@ describe('bitbucket:pipelines:run', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createBitbucketPipelinesRunAction({ integrations });
const mockContext = {
input: {},
workspacePath: 'wsp',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
const workspace = 'test-workspace';
const repo_slug = 'test-repo-slug';
const responseJson = {
@@ -50,6 +50,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -32,9 +32,8 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:bitbucketServer', () => {
const config = new ConfigReader({
@@ -60,17 +59,12 @@ describe('publish:bitbucketServer', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishBitbucketServerAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'hosted.bitbucket.com?project=project&repo=repo',
repoVisibility: 'private' as const,
},
workspacePath: 'wsp',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -32,8 +32,7 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:bitbucketServer:pull-request', () => {
const config = new ConfigReader({
@@ -62,7 +61,7 @@ describe('publish:bitbucketServer:pull-request', () => {
integrations,
config,
});
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'hosted.bitbucket.com?project=project&repo=repo',
title: 'Add Scaffolder actions for Bitbucket Server',
@@ -71,12 +70,7 @@ describe('publish:bitbucketServer:pull-request', () => {
targetBranch: 'master',
sourceBranch: 'develop',
},
workspacePath: 'wsp',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const responseOfBranches = {
size: 3,
limit: 25,
@@ -53,6 +53,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -32,12 +32,11 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import yaml from 'yaml';
import { sep } from 'path';
import { examples } from './bitbucket.examples';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:bitbucket', () => {
const config = new ConfigReader({
@@ -61,17 +60,12 @@ describe('publish:bitbucket', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishBitbucketAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo',
repoVisibility: 'private' as const,
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -31,9 +31,8 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:bitbucket', () => {
const config = new ConfigReader({
@@ -57,17 +56,12 @@ describe('publish:bitbucket', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishBitbucketAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'bitbucket.org?workspace=workspace&project=project&repo=repo',
repoVisibility: 'private' as const,
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -54,6 +54,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -13,7 +13,6 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createConfluenceToMarkdownAction } from './confluenceToMarkdown';
import { getVoidLogger } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
@@ -28,6 +27,7 @@ import { setupServer } from 'msw/node';
import { examples } from './confluenceToMarkdown.examples';
import yaml from 'yaml';
import { ActionContext } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('confluence:transform:markdown examples', () => {
const baseUrl = `https://confluence.example.com`;
@@ -71,14 +71,11 @@ describe('confluence:transform:markdown examples', () => {
}),
search: jest.fn(),
};
mockContext = {
mockContext = createMockActionContext({
input: yaml.parse(examples[0].example).steps[0].input,
workspacePath,
logger,
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
mockDir.setContent({ 'workspace/mkdocs.yml': 'File contents' });
});
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createConfluenceToMarkdownAction } from './confluenceToMarkdown';
import { getVoidLogger } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
@@ -26,6 +26,7 @@ import {
import type { ActionContext } from '@backstage/plugin-scaffolder-node';
import { rest } from 'msw';
import { setupServer } from 'msw/node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('confluence:transform:markdown', () => {
const baseUrl = `https://nodomain.confluence.com`;
@@ -69,7 +70,7 @@ describe('confluence:transform:markdown', () => {
}),
search: jest.fn(),
};
mockContext = {
mockContext = createMockActionContext({
input: {
confluenceUrls: [
'https://nodomain.confluence.com/display/testing/mkdocs',
@@ -79,10 +80,7 @@ describe('confluence:transform:markdown', () => {
},
workspacePath,
logger,
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
mockDir.setContent({ 'workspace/mkdocs.yml': 'File contents' });
});
@@ -53,6 +53,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@types/command-exists": "^1.2.0",
"@types/fs-extra": "^11.0.0"
},
@@ -14,19 +14,15 @@
* limitations under the License.
*/
import {
getVoidLogger,
UrlReader,
ContainerRunner,
} from '@backstage/backend-common';
import { UrlReader, ContainerRunner } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { JsonObject } from '@backstage/types';
import { ScmIntegrations } from '@backstage/integration';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { PassThrough } from 'stream';
import { createFetchCookiecutterAction } from './cookiecutter';
import { join } from 'path';
import type { ActionContext } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
const executeShellCommand = jest.fn();
const commandExists = jest.fn();
@@ -88,7 +84,7 @@ describe('fetch:cookiecutter', () => {
beforeEach(() => {
jest.resetAllMocks();
mockContext = {
mockContext = createMockActionContext({
input: {
url: 'https://google.com/cookie/cutter',
targetPath: 'something',
@@ -101,11 +97,7 @@ describe('fetch:cookiecutter', () => {
baseUrl: 'somebase',
},
workspacePath: mockTmpDir,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir),
};
});
mockDir.setContent({ template: {} });
commandExists.mockResolvedValue(null);
@@ -49,6 +49,7 @@
"@backstage/backend-common": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -33,9 +33,8 @@ import { setupServer } from 'msw/node';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:gerrit', () => {
const config = new ConfigReader({
@@ -53,18 +52,13 @@ describe('publish:gerrit', () => {
const description = 'for the lols';
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishGerritAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl:
'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo',
description,
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -24,9 +24,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
import { createPublishGerritReviewAction } from './gerritReview';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { commitAndPushRepo } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('publish:gerrit:review', () => {
const config = new ConfigReader({
@@ -43,18 +42,13 @@ describe('publish:gerrit:review', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishGerritReviewAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl:
'gerrithost.org?owner=owner&workspace=parent&project=project&repo=repo',
gitCommitMessage: 'Review from backstage',
},
workspacePath: 'workspace',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -49,6 +49,7 @@
"@backstage/backend-common": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"msw": "^1.0.0"
},
"files": [
@@ -13,14 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { createPublishGiteaAction } from './gitea';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { rest } from 'msw';
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { setupServer } from 'msw/node';
jest.mock('@backstage/plugin-scaffolder-node', () => {
@@ -48,17 +47,12 @@ describe('publish:gitea', () => {
const description = 'for the lols';
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishGiteaAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitea.com?repo=repo&owner=owner',
description,
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
const server = setupServer();
setupRequestMockHandlers(server);
@@ -53,6 +53,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@types/libsodium-wrappers": "^0.7.10",
"fs-extra": "^11.2.0",
"jest-when": "^3.1.0",
@@ -36,14 +36,13 @@ import {
TemplateAction,
initRepoAndPush,
} from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createPublishGithubAction } from './github';
import { examples } from './github.examples';
import yaml from 'yaml';
@@ -101,19 +100,14 @@ describe('publish:github', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
description: 'description',
repoVisibility: 'private' as const,
access: 'owner/blam',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
initRepoAndPushMocked.mockResolvedValue({
@@ -34,15 +34,14 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
});
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { when } from 'jest-when';
import { PassThrough } from 'stream';
import { createPublishGithubAction } from './github';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import {
@@ -103,19 +102,14 @@ describe('publish:github', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
description: 'description',
repoVisibility: 'private' as const,
access: 'owner/blam',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
initRepoAndPushMocked.mockResolvedValue({
@@ -20,10 +20,9 @@ import {
GithubCredentialsProvider,
} from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
import { createGithubActionsDispatchAction } from './githubActionsDispatch';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import yaml from 'yaml';
import { examples } from './githubActionsDispatch.examples';
@@ -56,18 +55,13 @@ describe('github:actions:dispatch', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
workflowId: 'a-workflow-id',
branchOrTagName: 'main',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -20,9 +20,8 @@ import {
GithubCredentialsProvider,
} from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createGithubActionsDispatchAction } from './githubActionsDispatch';
const mockOctokit = {
@@ -54,18 +53,13 @@ describe('github:actions:dispatch', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
workflowId: 'a-workflow-id',
branchOrTagName: 'main',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -14,7 +14,6 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
@@ -22,8 +21,8 @@ import {
ScmIntegrations,
} from '@backstage/integration';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
import { createGithubAutolinksAction } from './githubAutolinks';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { examples } from './githubAutolinks.examples';
import yaml from 'yaml';
@@ -55,9 +54,12 @@ describe('github:autolinks:create', () => {
const integrations = ScmIntegrations.fromConfig(config);
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any, any>;
const input = yaml.parse(examples[0].example).steps[0].input;
const mockContext = createMockActionContext({
input,
});
it('should call the githubApis for creating autolink reference', async () => {
const input = yaml.parse(examples[0].example).steps[0].input;
githubCredentialsProvider =
DefaultGithubCredentialsProvider.fromIntegrations(integrations);
action = createGithubAutolinksAction({
@@ -70,14 +72,7 @@ describe('github:autolinks:create', () => {
id: '1',
},
});
await action.handler({
input,
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
});
await action.handler(mockContext);
expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({
owner: 'owner',
@@ -14,15 +14,15 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
import { createGithubAutolinksAction } from './githubAutolinks';
const mockOctokit = {
@@ -53,13 +53,7 @@ describe('github:autolinks:create', () => {
const integrations = ScmIntegrations.fromConfig(config);
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any, any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const workspacePath = createMockDirectory().resolve('workspace');
it('should call the githubApis for creating alphanumeric autolink reference', async () => {
githubCredentialsProvider =
@@ -74,14 +68,16 @@ describe('github:autolinks:create', () => {
id: '1',
},
});
await action.handler({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
keyPrefix: 'TICKET-',
urlTemplate: 'https://example.com/TICKET?query=<num>',
},
...mockContext,
});
await action.handler(
createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
keyPrefix: 'TICKET-',
urlTemplate: 'https://example.com/TICKET?query=<num>',
},
workspacePath,
}),
);
expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({
owner: 'owner',
@@ -104,15 +100,17 @@ describe('github:autolinks:create', () => {
id: '1',
},
});
await action.handler({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
keyPrefix: 'TICKET-',
urlTemplate: 'https://example.com/TICKET?query=<num>',
isAlphanumeric: false,
},
...mockContext,
});
await action.handler(
createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
keyPrefix: 'TICKET-',
urlTemplate: 'https://example.com/TICKET?query=<num>',
isAlphanumeric: false,
},
workspacePath,
}),
);
expect(mockOctokit.rest.repos.createAutolink).toHaveBeenCalledWith({
owner: 'owner',
@@ -14,11 +14,10 @@
* limitations under the License.
*/
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createGithubDeployKeyAction } from './githubDeployKey';
import yaml from 'yaml';
import { examples } from './githubDeployKey.examples';
import { PassThrough } from 'stream';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -55,13 +54,7 @@ describe('Usage examples', () => {
const integrations = ScmIntegrations.fromConfig(config);
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
@@ -14,10 +14,9 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createGithubDeployKeyAction } from './githubDeployKey';
import { getVoidLogger } from '@backstage/backend-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -55,19 +54,14 @@ describe('github:deployKey:create', () => {
const integrations = ScmIntegrations.fromConfig(config);
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repository&owner=owner',
publicKey: 'pubkey',
privateKey: 'privkey',
deployKeyName: 'Push Tags',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -13,9 +13,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createGithubEnvironmentAction } from './githubEnvironment';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -59,13 +58,7 @@ describe('github:environment:create examples', () => {
const integrations = ScmIntegrations.fromConfig(config);
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
mockOctokit.rest.actions.getEnvironmentPublicKey.mockResolvedValue({
@@ -14,9 +14,8 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createGithubEnvironmentAction } from './githubEnvironment';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -58,17 +57,12 @@ describe('github:environment:create', () => {
const integrations = ScmIntegrations.fromConfig(config);
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repository&owner=owner',
name: 'envname',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
mockOctokit.rest.actions.getEnvironmentPublicKey.mockResolvedValue({
@@ -15,14 +15,13 @@
*/
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createGithubIssuesLabelAction } from './githubIssuesLabel';
import yaml from 'yaml';
import { examples } from './githubIssuesLabel.examples';
@@ -64,13 +63,7 @@ describe('github:issues:label examples', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
@@ -20,10 +20,9 @@ import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
} from '@backstage/integration';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
import { getOctokitOptions } from './helpers';
jest.mock('./helpers', () => {
@@ -62,18 +61,13 @@ describe('github:issues:label', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
number: '1',
labels: ['label1', 'label2'],
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -15,14 +15,13 @@
*/
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createPublishGithubPullRequestAction } from './githubPullRequest';
import yaml from 'yaml';
import { examples } from './githubPullRequest.examples';
@@ -57,13 +56,7 @@ describe('publish:github:pull-request examples', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
let fakeClient: {
createPullRequest: jest.Mock;
rest: {
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { createRootLogger, getRootLogger } from '@backstage/backend-common';
import { createRootLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
GithubCredentialsProvider,
@@ -25,9 +25,9 @@ import {
TemplateAction,
} from '@backstage/plugin-scaffolder-node';
import fs from 'fs-extra';
import { Writable } from 'stream';
import { createPublishGithubPullRequestAction } from './githubPullRequest';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
// Make sure root logger is initialized ahead of FS mock
createRootLogger();
@@ -131,14 +131,7 @@ describe('createPublishGithubPullRequestAction', () => {
[workspacePath]: { 'file.txt': 'Hello there!' },
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
@@ -196,14 +189,7 @@ describe('createPublishGithubPullRequestAction', () => {
[workspacePath]: { 'file.txt': 'Hello there!' },
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
@@ -263,14 +249,7 @@ describe('createPublishGithubPullRequestAction', () => {
},
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request with only relevant files', async () => {
@@ -322,14 +301,7 @@ describe('createPublishGithubPullRequestAction', () => {
[workspacePath]: { 'file.txt': 'Hello there!' },
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
await instance.handler(ctx);
@@ -382,14 +354,7 @@ describe('createPublishGithubPullRequestAction', () => {
mockDir.setContent({ [workspacePath]: {} });
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request and requests a review from the given reviewers', async () => {
@@ -434,14 +399,7 @@ describe('createPublishGithubPullRequestAction', () => {
mockDir.setContent({ [workspacePath]: {} });
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('does not call the API endpoint for requesting reviewers', async () => {
@@ -470,14 +428,7 @@ describe('createPublishGithubPullRequestAction', () => {
},
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
await instance.handler(ctx);
@@ -526,14 +477,7 @@ describe('createPublishGithubPullRequestAction', () => {
},
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
await instance.handler(ctx);
@@ -592,14 +536,7 @@ describe('createPublishGithubPullRequestAction', () => {
},
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
await instance.handler(ctx);
@@ -653,14 +590,7 @@ describe('createPublishGithubPullRequestAction', () => {
[workspacePath]: { 'file.txt': 'Hello there!' },
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
@@ -705,14 +635,7 @@ describe('createPublishGithubPullRequestAction', () => {
[workspacePath]: { 'file.txt': 'Hello there!' },
});
ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
ctx = createMockActionContext({ input, workspacePath });
});
it('creates a pull request', async () => {
@@ -23,14 +23,13 @@ jest.mock('./gitHelpers', () => {
};
});
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createGithubRepoCreateAction } from './githubRepoCreate';
import { entityRefToName } from './gitHelpers';
import yaml from 'yaml';
@@ -82,16 +81,11 @@ describe('github:repo:create examples', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
githubCredentialsProvider =
@@ -15,6 +15,7 @@
*/
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
jest.mock('./gitHelpers', () => {
return {
@@ -23,7 +24,6 @@ jest.mock('./gitHelpers', () => {
};
});
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
@@ -31,7 +31,6 @@ import {
ScmIntegrations,
} from '@backstage/integration';
import { when } from 'jest-when';
import { PassThrough } from 'stream';
import { createGithubRepoCreateAction } from './githubRepoCreate';
import { entityRefToName } from './gitHelpers';
@@ -82,19 +81,14 @@ describe('github:repo:create', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
description: 'description',
repoVisibility: 'private' as const,
access: 'owner/blam',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
githubCredentialsProvider =
@@ -29,14 +29,13 @@ import {
TemplateAction,
initRepoAndPush,
} from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createGithubRepoPushAction } from './githubRepoPush';
import { examples } from './githubRepoPush.examples';
import yaml from 'yaml';
@@ -102,13 +101,7 @@ describe('github:repo:push examples', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
@@ -59,14 +59,13 @@ import {
TemplateAction,
initRepoAndPush,
} from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { enableBranchProtectionOnDefaultRepoBranch } from './gitHelpers';
import { createGithubRepoPushAction } from './githubRepoPush';
@@ -103,19 +102,14 @@ describe('github:repo:push', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repository&owner=owner',
description: 'description',
repoVisibility: 'private' as const,
access: 'owner/blam',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -14,14 +14,13 @@
* limitations under the License.
*/
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
ScmIntegrations,
} from '@backstage/integration';
import { PassThrough } from 'stream';
import { createGithubWebhookAction } from './githubWebhook';
import yaml from 'yaml';
import { examples } from './githubWebhook.examples';
@@ -56,13 +55,7 @@ describe('github:webhook examples', () => {
let githubCredentialsProvider: GithubCredentialsProvider;
let action: TemplateAction<any>;
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
@@ -20,10 +20,9 @@ import {
DefaultGithubCredentialsProvider,
GithubCredentialsProvider,
} from '@backstage/integration';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { PassThrough } from 'stream';
const mockOctokit = {
rest: {
@@ -66,17 +65,12 @@ describe('github:repository:webhook:create', () => {
});
});
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'github.com?repo=repo&owner=owner',
webhookUrl: 'https://example.com/payload',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
it('should call the githubApi for creating repository Webhook', async () => {
const repoUrl = 'github.com?repo=repo&owner=owner';
@@ -57,6 +57,7 @@
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/core-app-api": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"jest-date-mock": "^1.0.8"
},
"files": [
@@ -14,9 +14,8 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { createGitlabGroupEnsureExistsAction } from './createGitlabGroupEnsureExistsAction';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/core-app-api';
import { ScmIntegrations } from '@backstage/integration';
@@ -35,13 +34,7 @@ jest.mock('@gitbeaker/node', () => ({
}));
describe('gitlab:group:ensureExists', () => {
const mockContext = {
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
afterEach(() => {
jest.resetAllMocks();
@@ -14,8 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createGitlabIssueAction, IssueType } from './createGitlabIssueAction';
import { ConfigReader } from '@backstage/core-app-api';
import { ScmIntegrations } from '@backstage/integration';
@@ -60,18 +59,14 @@ describe('gitlab:issues:create', () => {
const action = createGitlabIssueAction({ integrations });
it('should return a Gitlab issue when called with minimal input params', async () => {
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
projectId: 123,
title: 'Computer banks to rule the world',
},
workspacePath: 'seen2much',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
mockGitlabClient.Issues.create.mockResolvedValue({
id: 42,
@@ -109,7 +104,7 @@ describe('gitlab:issues:create', () => {
});
it('should return a Gitlab issue when called with oAuth Token', async () => {
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
projectId: 123,
@@ -117,11 +112,7 @@ describe('gitlab:issues:create', () => {
token: 'myAwesomeToken',
},
workspacePath: 'seen2much',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
mockGitlabClient.Issues.create.mockResolvedValue({
id: 42,
@@ -159,7 +150,7 @@ describe('gitlab:issues:create', () => {
});
it('should return a Gitlab issue when called with several input params', async () => {
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
projectId: 123,
@@ -173,11 +164,7 @@ describe('gitlab:issues:create', () => {
labels: 'operation:mindcrime',
},
workspacePath: 'seen2much',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
mockGitlabClient.Issues.create.mockResolvedValue({
id: 42,
@@ -13,13 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { PassThrough } from 'stream';
import yaml from 'yaml';
import { createGitlabProjectAccessTokenAction } from './createGitlabProjectAccessTokenAction'; // Adjust the import based on your project structure
import { examples } from './createGitlabProjectAccessTokenAction.examples';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { DateTime } from 'luxon';
@@ -59,16 +58,11 @@ describe('gitlab:projectAccessToken:create examples', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createGitlabProjectAccessTokenAction({ integrations });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -15,10 +15,9 @@
*/
import { createGitlabProjectDeployTokenAction } from './createGitlabProjectDeployTokenAction';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
const mockGitlabClient = {
ProjectDeployTokens: {
@@ -52,7 +51,7 @@ describe('gitlab:create-deploy-token', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createGitlabProjectDeployTokenAction({ integrations });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
projectId: '123',
@@ -60,12 +59,7 @@ describe('gitlab:create-deploy-token', () => {
username: 'tokenuser',
scopes: ['read_repository'],
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -14,6 +14,7 @@
* limitations under the License.
*/
import yaml from 'yaml';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
jest.mock('@backstage/plugin-scaffolder-node', () => {
return {
@@ -31,8 +32,6 @@ import { createPublishGitlabAction } from './gitlab';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { examples } from './gitlab.examples';
const mockGitlabClient = {
@@ -76,16 +75,11 @@ describe('publish:gitlab', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishGitlabAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -29,9 +29,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
import { createPublishGitlabAction } from './gitlab';
import { ScmIntegrations } from '@backstage/integration';
import { ConfigReader } from '@backstage/config';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { initRepoAndPush } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
const mockGitlabClient = {
Namespaces: {
@@ -83,7 +82,8 @@ describe('publish:gitlab', () => {
const integrations = ScmIntegrations.fromConfig(config);
const action = createPublishGitlabAction({ integrations, config });
const mockContext = {
const mockContext = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
repoVisibility: 'private' as const,
@@ -91,13 +91,8 @@ describe('publish:gitlab', () => {
ci_config_path: '.gitlab-ci.yml',
},
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContextWithSettings = {
});
const mockContextWithSettings = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
repoVisibility: 'private' as const,
@@ -108,13 +103,8 @@ describe('publish:gitlab', () => {
topics: ['topic1', 'topic2'],
},
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContextWithBranches = {
});
const mockContextWithBranches = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
repoVisibility: 'private' as const,
@@ -135,13 +125,8 @@ describe('publish:gitlab', () => {
},
],
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContextWithVariables = {
});
const mockContextWithVariables = createMockActionContext({
input: {
repoUrl: 'gitlab.com?repo=repo&owner=owner',
repoVisibility: 'private' as const,
@@ -155,12 +140,7 @@ describe('publish:gitlab', () => {
},
],
},
workspacePath: 'lol',
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createRootLogger, getRootLogger } from '@backstage/backend-common';
import { createRootLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { Writable } from 'stream';
import { createPublishGitlabMergeRequestAction } from './gitlabMergeRequest';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
// Make sure root logger is initialized ahead of FS mock
createRootLogger();
@@ -118,14 +118,7 @@ describe('createGitLabMergeRequest', () => {
irrelevant: { 'bar.txt': 'Nothing to see here' },
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Projects.show).not.toHaveBeenCalled();
@@ -160,14 +153,7 @@ describe('createGitLabMergeRequest', () => {
irrelevant: { 'bar.txt': 'Nothing to see here' },
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Projects.show).toHaveBeenCalledWith('owner/repo');
@@ -205,14 +191,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -240,14 +219,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -281,14 +253,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -321,14 +286,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -361,14 +319,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -400,14 +351,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.MergeRequests.create).toHaveBeenCalledWith(
@@ -435,14 +379,7 @@ describe('createGitLabMergeRequest', () => {
irrelevant: { 'bar.txt': 'Nothing to see here' },
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
@@ -484,14 +421,7 @@ describe('createGitLabMergeRequest', () => {
irrelevant: { 'bar.txt': 'Nothing to see here' },
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
@@ -528,14 +458,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
@@ -570,14 +493,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
@@ -612,14 +528,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Commits.create).toHaveBeenCalledWith(
@@ -657,14 +566,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
@@ -702,14 +604,7 @@ describe('createGitLabMergeRequest', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
@@ -739,14 +634,7 @@ describe('createGitLabMergeRequest', () => {
commitAction: 'create',
};
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await expect(instance.handler(ctx)).rejects.toThrow(
'Relative path is not allowed to refer to a directory outside its parent',
@@ -13,13 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { createRootLogger, getRootLogger } from '@backstage/backend-common';
import { createRootLogger } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { TemplateAction } from '@backstage/plugin-scaffolder-node';
import { Writable } from 'stream';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createGitlabRepoPushAction } from './gitlabRepoPush';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
// Make sure root logger is initialized ahead of FS mock
createRootLogger();
@@ -93,14 +93,7 @@ describe('createGitLabCommit', () => {
'foo.txt': 'Hello there!',
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0);
@@ -139,14 +132,7 @@ describe('createGitLabCommit', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0);
@@ -183,14 +169,7 @@ describe('createGitLabCommit', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0);
@@ -227,14 +206,7 @@ describe('createGitLabCommit', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Branches.create).toHaveBeenCalledTimes(0);
@@ -276,14 +248,7 @@ describe('createGitLabCommit', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
@@ -325,14 +290,7 @@ describe('createGitLabCommit', () => {
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
@@ -366,14 +324,7 @@ describe('createGitLabCommit', () => {
commitAction: 'create',
};
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await expect(instance.handler(ctx)).rejects.toThrow(
'Relative path is not allowed to refer to a directory outside its parent',
@@ -398,14 +349,7 @@ describe('createGitLabCommit', () => {
'foo.txt': 'Hello there!',
},
});
const ctx = {
createTemporaryDirectory: jest.fn(),
output: jest.fn(),
logger: getRootLogger(),
logStream: new Writable(),
input,
workspacePath,
};
const ctx = createMockActionContext({ input, workspacePath });
await instance.handler(ctx);
expect(mockGitlabClient.Branches.create).toHaveBeenCalledWith(
@@ -51,6 +51,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@types/command-exists": "^1.2.0",
"@types/fs-extra": "^11.0.0",
"@types/node": "^18.17.8",
@@ -27,18 +27,14 @@ jest.mock('./railsNewRunner', () => {
};
});
import {
ContainerRunner,
getVoidLogger,
UrlReader,
} from '@backstage/backend-common';
import { ContainerRunner, UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { resolve as resolvePath } from 'path';
import { PassThrough } from 'stream';
import { createFetchRailsAction } from './index';
import { fetchContents } from '@backstage/plugin-scaffolder-node';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('fetch:rails', () => {
const mockDir = createMockDirectory();
@@ -53,8 +49,7 @@ describe('fetch:rails', () => {
}),
);
const mockTmpDir = mockDir.path;
const mockContext = {
const mockContext = createMockActionContext({
input: {
url: 'https://rubyonrails.org/generator',
targetPath: 'something',
@@ -66,12 +61,8 @@ describe('fetch:rails', () => {
baseUrl: 'somebase',
entityRef: 'template:default/myTemplate',
},
workspacePath: mockTmpDir,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir),
};
workspacePath: mockDir.path,
});
const mockReader: UrlReader = {
readUrl: jest.fn(),
@@ -102,7 +93,7 @@ describe('fetch:rails', () => {
expect(fetchContents).toHaveBeenCalledWith({
reader: mockReader,
integrations,
baseUrl: mockContext.templateInfo.baseUrl,
baseUrl: mockContext.templateInfo?.baseUrl,
fetchUrl: mockContext.input.url,
outputPath: resolvePath(mockContext.workspacePath),
});
@@ -112,7 +103,7 @@ describe('fetch:rails', () => {
await action.handler(mockContext);
expect(mockRailsTemplater.run).toHaveBeenCalledWith({
workspacePath: mockTmpDir,
workspacePath: mockContext.workspacePath,
logStream: mockContext.logStream,
values: mockContext.input.values,
});
@@ -128,7 +119,7 @@ describe('fetch:rails', () => {
});
expect(mockRailsTemplater.run).toHaveBeenCalledWith({
workspacePath: mockTmpDir,
workspacePath: mockContext.workspacePath,
logStream: mockContext.logStream,
values: {
...mockContext.input.values,
@@ -46,6 +46,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@backstage/types": "workspace:^",
"msw": "^2.0.0"
},
@@ -15,6 +15,7 @@
*/
import { setupRequestMockHandlers } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ConfigReader } from '@backstage/config';
import { InputError } from '@backstage/errors';
import { ActionContext } from '@backstage/plugin-scaffolder-node';
@@ -42,19 +43,17 @@ describe('sentry:project:create action', () => {
name: string;
slug?: string;
authToken?: string;
}> => ({
workspacePath: './dev/proj',
createTemporaryDirectory: jest.fn(),
logger: jest.createMockFromModule('winston'),
logStream: jest.createMockFromModule('stream'),
input: {
organizationSlug: 'org',
teamSlug: 'team',
name: 'test project',
authToken: randomBytes(5).toString('hex'),
},
output: jest.fn(),
});
}> =>
createMockActionContext({
workspacePath: './dev/proj',
logger: jest.createMockFromModule('winston'),
input: {
organizationSlug: 'org',
teamSlug: 'team',
name: 'test project',
authToken: randomBytes(5).toString('hex'),
},
});
it('should request sentry project create with specified parameters.', async () => {
expect.assertions(3);
@@ -39,6 +39,7 @@
"dependencies": {
"@backstage/backend-plugin-api": "workspace:^",
"@backstage/plugin-scaffolder-node": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@backstage/types": "workspace:^",
"winston": "^3.2.1",
"yeoman-environment": "^3.9.1"
@@ -18,9 +18,8 @@ import { yeomanRun } from './yeomanRun';
jest.mock('./yeomanRun');
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import os from 'os';
import { PassThrough } from 'stream';
import { createRunYeomanAction } from './yeoman';
import type { ActionContext } from '@backstage/plugin-scaffolder-node';
import { JsonObject } from '@backstage/types';
@@ -46,18 +45,14 @@ describe('run:yeoman', () => {
const options = {
code: 'owner',
};
mockContext = {
mockContext = createMockActionContext({
input: {
namespace,
args,
options,
},
workspacePath: mockTmpDir,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn().mockResolvedValue(mockTmpDir),
};
});
await action.handler(mockContext);
expect(yeomanRun).toHaveBeenCalledWith(
+1
View File
@@ -95,6 +95,7 @@
"devDependencies": {
"@backstage/backend-test-utils": "workspace:^",
"@backstage/cli": "workspace:^",
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^",
"@types/fs-extra": "^11.0.0",
"@types/nunjucks": "^3.1.4",
"@types/supertest": "^2.0.8",
@@ -14,9 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { createFetchCatalogEntityAction } from './fetch';
@@ -36,14 +34,9 @@ describe('catalog:fetch examples', () => {
catalogClient: catalogClient as unknown as CatalogApi,
});
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
const mockContext = createMockActionContext({
secrets: { backstageToken: 'secret' },
};
});
beforeEach(() => {
jest.resetAllMocks();
});
@@ -14,9 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { CatalogApi } from '@backstage/catalog-client';
import { Entity } from '@backstage/catalog-model';
import { createFetchCatalogEntityAction } from './fetch';
@@ -34,14 +32,10 @@ describe('catalog:fetch', () => {
catalogClient: catalogClient as unknown as CatalogApi,
});
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
const mockContext = createMockActionContext({
secrets: { backstageToken: 'secret' },
};
});
beforeEach(() => {
jest.resetAllMocks();
});
@@ -14,9 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { CatalogApi } from '@backstage/catalog-client';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -44,13 +42,7 @@ describe('catalog:register', () => {
catalogClient: catalogClient as unknown as CatalogApi,
});
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
});
@@ -14,9 +14,7 @@
* limitations under the License.
*/
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { CatalogApi } from '@backstage/catalog-client';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
@@ -42,13 +40,8 @@ describe('catalog:register', () => {
catalogClient: catalogClient as unknown as CatalogApi,
});
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
beforeEach(() => {
jest.resetAllMocks();
});
@@ -20,24 +20,16 @@ jest.mock('fs-extra');
const fsMock = fs as jest.Mocked<typeof fs>;
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createCatalogWriteAction } from './write';
import { resolve as resolvePath } from 'path';
import * as yaml from 'yaml';
import { examples } from './write.examples';
import os from 'os';
describe('catalog:write', () => {
const action = createCatalogWriteAction();
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext({ workspacePath: os.tmpdir() });
beforeEach(() => {
jest.resetAllMocks();
@@ -20,9 +20,8 @@ jest.mock('fs-extra');
const fsMock = fs as jest.Mocked<typeof fs>;
import { PassThrough } from 'stream';
import os from 'os';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { ANNOTATION_ORIGIN_LOCATION } from '@backstage/catalog-model';
import { createCatalogWriteAction } from './write';
import { resolve as resolvePath } from 'path';
@@ -31,18 +30,14 @@ import * as yaml from 'yaml';
describe('catalog:write', () => {
const action = createCatalogWriteAction();
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
beforeEach(() => {
jest.resetAllMocks();
});
const mockContext = createMockActionContext({
workspacePath: os.tmpdir(),
});
it('should write the catalog-info.yml in the workspace', async () => {
const entity = {
apiVersion: 'backstage.io/v1alpha1',
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { Writable } from 'stream';
import { createDebugLogAction } from './log';
import { join } from 'path';
@@ -30,15 +30,10 @@ describe('debug:log examples', () => {
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const mockContext = {
input: {},
baseUrl: 'somebase',
workspacePath,
logger: getVoidLogger(),
const mockContext = createMockActionContext({
logStream,
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
workspacePath,
});
const action = createDebugLogAction();
@@ -51,12 +46,10 @@ describe('debug:log examples', () => {
});
it('should log message', async () => {
const context = {
await action.handler({
...mockContext,
input: yaml.parse(examples[0].example).steps[0].input,
};
await action.handler(context);
});
expect(logStream.write).toHaveBeenCalledTimes(1);
expect(logStream.write).toHaveBeenCalledWith(
@@ -65,12 +58,10 @@ describe('debug:log examples', () => {
});
it('should log the workspace content, if active', async () => {
const context = {
await action.handler({
...mockContext,
input: yaml.parse(examples[1].example).steps[0].input,
};
await action.handler(context);
});
expect(logStream.write).toHaveBeenCalledTimes(1);
expect(logStream.write).toHaveBeenCalledWith(
@@ -14,7 +14,7 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { Writable } from 'stream';
import { createDebugLogAction } from './log';
import { join } from 'path';
@@ -29,15 +29,7 @@ describe('debug:log', () => {
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const mockContext = {
input: {},
baseUrl: 'somebase',
workspacePath,
logger: getVoidLogger(),
logStream,
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext({ workspacePath, logStream });
const action = createDebugLogAction();
@@ -14,12 +14,11 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { createWaitAction } from './wait';
import { Writable } from 'stream';
import { examples } from './wait.examples';
import yaml from 'yaml';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('debug:wait examples', () => {
const action = createWaitAction();
@@ -28,18 +27,9 @@ describe('debug:wait examples', () => {
write: jest.fn(),
} as jest.Mocked<Partial<Writable>> as jest.Mocked<Writable>;
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const mockContext = {
input: {},
baseUrl: 'somebase',
workspacePath,
logger: getVoidLogger(),
const mockContext = createMockActionContext({
logStream,
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -14,10 +14,9 @@
* limitations under the License.
*/
import { getVoidLogger } from '@backstage/backend-common';
import { createWaitAction } from './wait';
import { Writable } from 'stream';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
describe('debug:wait', () => {
const action = createWaitAction();
@@ -26,18 +25,9 @@ describe('debug:wait', () => {
write: jest.fn(),
} as jest.Mocked<Partial<Writable>> as jest.Mocked<Writable>;
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const mockContext = {
input: {},
baseUrl: 'somebase',
workspacePath,
logger: getVoidLogger(),
const mockContext = createMockActionContext({
logStream,
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.resetAllMocks();
@@ -16,14 +16,13 @@
import yaml from 'yaml';
import os from 'os';
import { resolve as resolvePath } from 'path';
import { getVoidLogger, UrlReader } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { createFetchPlainAction } from './plain';
import { PassThrough } from 'stream';
import { fetchContents } from '@backstage/plugin-scaffolder-node';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { examples } from './plain.examples';
jest.mock('@backstage/plugin-scaffolder-node', () => ({
@@ -50,19 +49,15 @@ describe('fetch:plain examples', () => {
});
const action = createFetchPlainAction({ integrations, reader });
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
it('should fetch plain', async () => {
await action.handler({
...mockContext,
input: yaml.parse(examples[0].example).steps[0].input,
});
await action.handler(
createMockActionContext({
...mockContext,
input: yaml.parse(examples[0].example).steps[0].input,
}),
);
expect(fetchContents).toHaveBeenCalledWith(
expect.objectContaining({
outputPath: resolvePath(mockContext.workspacePath),
@@ -19,14 +19,13 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
return { ...actual, fetchContents: jest.fn() };
});
import os from 'os';
import { resolve as resolvePath } from 'path';
import { getVoidLogger, UrlReader } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { fetchContents } from '@backstage/plugin-scaffolder-node';
import { createFetchPlainAction } from './plain';
import { PassThrough } from 'stream';
describe('fetch:plain', () => {
const integrations = ScmIntegrations.fromConfig(
@@ -47,13 +46,7 @@ describe('fetch:plain', () => {
});
const action = createFetchPlainAction({ integrations, reader });
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
it('should disallow a target path outside working directory', async () => {
await expect(
@@ -14,19 +14,19 @@
* limitations under the License.
*/
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
jest.mock('@backstage/plugin-scaffolder-node', () => {
const actual = jest.requireActual('@backstage/plugin-scaffolder-node');
return { ...actual, fetchFile: jest.fn() };
});
import yaml from 'yaml';
import os from 'os';
import { resolve as resolvePath } from 'path';
import { getVoidLogger, UrlReader } from '@backstage/backend-common';
import { UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { createFetchPlainFileAction } from './plainFile';
import { PassThrough } from 'stream';
import { fetchFile } from '@backstage/plugin-scaffolder-node';
import { examples } from './plainFile.examples';
@@ -49,13 +49,7 @@ describe('fetch:plain:file examples', () => {
});
const action = createFetchPlainFileAction({ integrations, reader });
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
it('should fetch plain', async () => {
await action.handler({
@@ -19,14 +19,13 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
return { ...actual, fetchFile: jest.fn() };
});
import os from 'os';
import { resolve as resolvePath } from 'path';
import { getVoidLogger, UrlReader } from '@backstage/backend-common';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { UrlReader } from '@backstage/backend-common';
import { ConfigReader } from '@backstage/config';
import { ScmIntegrations } from '@backstage/integration';
import { fetchFile } from '@backstage/plugin-scaffolder-node';
import { createFetchPlainFileAction } from './plainFile';
import { PassThrough } from 'stream';
describe('fetch:plain:file', () => {
const integrations = ScmIntegrations.fromConfig(
@@ -47,13 +46,7 @@ describe('fetch:plain:file', () => {
});
const action = createFetchPlainFileAction({ integrations, reader });
const mockContext = {
workspacePath: os.tmpdir(),
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
const mockContext = createMockActionContext();
it('should disallow a target path outside working directory', async () => {
await expect(
@@ -16,13 +16,9 @@
import { join as joinPath, sep as pathSep } from 'path';
import fs from 'fs-extra';
import {
getVoidLogger,
resolvePackagePath,
UrlReader,
} from '@backstage/backend-common';
import { resolvePackagePath, UrlReader } from '@backstage/backend-common';
import { ScmIntegrations } from '@backstage/integration';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { createFetchTemplateAction } from './template';
import {
ActionContext,
@@ -61,23 +57,15 @@ describe('fetch:template examples', () => {
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const logger = getVoidLogger();
const mockContext = (input: any) => ({
templateInfo: {
baseUrl: 'base-url',
entityRef: 'template:default/test-template',
},
input: input,
output: jest.fn(),
logStream: new PassThrough(),
logger,
workspacePath,
async createTemporaryDirectory() {
return fs.mkdtemp(mockDir.resolve('tmp-'));
},
});
const mockContext = (input: any) =>
createMockActionContext({
templateInfo: {
baseUrl: 'base-url',
entityRef: 'template:default/test-template',
},
input,
workspacePath,
});
beforeEach(() => {
mockDir.clear();
@@ -21,13 +21,8 @@ jest.mock('@backstage/plugin-scaffolder-node', () => {
import { join as joinPath, sep as pathSep } from 'path';
import fs from 'fs-extra';
import {
getVoidLogger,
resolvePackagePath,
UrlReader,
} from '@backstage/backend-common';
import { resolvePackagePath, UrlReader } from '@backstage/backend-common';
import { ScmIntegrations } from '@backstage/integration';
import { PassThrough } from 'stream';
import { createFetchTemplateAction } from './template';
import {
fetchContents,
@@ -35,6 +30,7 @@ import {
TemplateAction,
} from '@backstage/plugin-scaffolder-node';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
type FetchTemplateInput = ReturnType<
typeof createFetchTemplateAction
@@ -59,29 +55,22 @@ describe('fetch:template', () => {
const mockDir = createMockDirectory();
const workspacePath = mockDir.resolve('workspace');
const logger = getVoidLogger();
const mockContext = (inputPatch: Partial<FetchTemplateInput> = {}) => ({
templateInfo: {
baseUrl: 'base-url',
entityRef: 'template:default/test-template',
},
input: {
url: './skeleton',
targetPath: './target',
values: {
test: 'value',
const mockContext = (inputPatch: Partial<FetchTemplateInput> = {}) =>
createMockActionContext({
templateInfo: {
baseUrl: 'base-url',
entityRef: 'template:default/test-template',
},
...inputPatch,
},
output: jest.fn(),
logStream: new PassThrough(),
logger,
workspacePath,
async createTemporaryDirectory() {
return fs.mkdtemp(mockDir.resolve('tmp-'));
},
});
input: {
url: './skeleton',
targetPath: './target',
values: {
test: 'value',
},
...inputPatch,
},
workspacePath,
});
beforeEach(() => {
mockDir.setContent({
@@ -15,8 +15,7 @@
*/
import { createFilesystemDeleteAction } from './delete';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import { resolve as resolvePath } from 'path';
import fs from 'fs-extra';
import yaml from 'yaml';
@@ -31,16 +30,12 @@ describe('fs:delete examples', () => {
const files: string[] = yaml.parse(examples[0].example).steps[0].input.files;
const mockContext = {
const mockContext = createMockActionContext({
input: {
files: files,
},
workspacePath,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.restoreAllMocks();
@@ -16,8 +16,7 @@
import { resolve as resolvePath } from 'path';
import { createFilesystemDeleteAction } from './delete';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import fs from 'fs-extra';
import { createMockDirectory } from '@backstage/backend-test-utils';
@@ -27,16 +26,12 @@ describe('fs:delete', () => {
const mockDir = createMockDirectory();
const workspacePath = resolvePath(mockDir.path, 'workspace');
const mockContext = {
const mockContext = createMockActionContext({
input: {
files: ['unit-test-a.js', 'unit-test-b.js'],
},
workspacePath,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.restoreAllMocks();
@@ -16,8 +16,7 @@
import { resolve as resolvePath } from 'path';
import { createFilesystemRenameAction } from './rename';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import fs from 'fs-extra';
import yaml from 'yaml';
import { examples } from './rename.examples';
@@ -31,16 +30,12 @@ describe('fs:rename examples', () => {
const mockDir = createMockDirectory();
const workspacePath = resolvePath(mockDir.path, 'workspace');
const mockContext = {
const mockContext = createMockActionContext({
input: {
files: files,
files,
},
workspacePath,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.restoreAllMocks();
@@ -16,8 +16,7 @@
import { resolve as resolvePath } from 'path';
import { createFilesystemRenameAction } from './rename';
import { getVoidLogger } from '@backstage/backend-common';
import { PassThrough } from 'stream';
import { createMockActionContext } from '@backstage/plugin-scaffolder-node-test-utils';
import fs from 'fs-extra';
import { createMockDirectory } from '@backstage/backend-test-utils';
@@ -41,16 +40,12 @@ describe('fs:rename', () => {
to: 'brand-new-folder',
},
];
const mockContext = {
const mockContext = createMockActionContext({
input: {
files: mockInputFiles,
},
workspacePath,
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
};
});
beforeEach(() => {
jest.restoreAllMocks();
@@ -0,0 +1 @@
module.exports = require('@backstage/cli/config/eslint-factory')(__dirname);
@@ -0,0 +1 @@
# @backstage/plugin-scaffolder-node-test-utils
@@ -0,0 +1,12 @@
# @backstage/plugin-scaffolder-node-test-utils
Contains utilities that can be used when testing scaffolder features.
## Installation
Install the package via Yarn into your own packages:
```sh
cd <package-dir> # if within a monorepo
yarn add --dev @backstage/plugin-scaffolder-node-test-utils
```
@@ -0,0 +1,33 @@
## API Report File for "@backstage/plugin-scaffolder-node-test-utils"
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
```ts
/// <reference types="node" />
import { ActionContext } from '@backstage/plugin-scaffolder-node';
import { JsonObject } from '@backstage/types';
import { TaskSecrets } from '@backstage/plugin-scaffolder-node';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
import * as winston from 'winston';
import { Writable } from 'stream';
// @public
export const createMockActionContext: <
TActionInput extends JsonObject = JsonObject,
TActionOutput extends JsonObject = JsonObject,
>(
options?:
| {
input?: TActionInput | undefined;
logger?: winston.Logger | undefined;
logStream?: Writable | undefined;
secrets?: TaskSecrets | undefined;
templateInfo?: TemplateInfo | undefined;
workspacePath?: string | undefined;
}
| undefined,
) => ActionContext<TActionInput, TActionOutput>;
// (No @packageDocumentation comment for this package)
```
@@ -0,0 +1,9 @@
apiVersion: backstage.io/v1alpha1
kind: Component
metadata:
name: backstage-plugin-scaffolder-node-test-utils
title: '@backstage/plugin-scaffolder-node-test-utils'
spec:
lifecycle: experimental
type: backstage-node-library
owner: maintainers
@@ -0,0 +1,2 @@
# Knip report
@@ -0,0 +1,46 @@
{
"name": "@backstage/plugin-scaffolder-node-test-utils",
"version": "0.0.1",
"backstage": {
"role": "node-library"
},
"publishConfig": {
"access": "public",
"main": "dist/index.esm.js",
"types": "dist/index.d.ts"
},
"repository": {
"type": "git",
"url": "https://github.com/backstage/backstage",
"directory": "plugins/scaffolder-node-test-utils"
},
"license": "Apache-2.0",
"sideEffects": false,
"main": "src/index.ts",
"types": "src/index.ts",
"files": [
"dist"
],
"scripts": {
"build": "backstage-cli package build",
"clean": "backstage-cli package clean",
"lint": "backstage-cli package lint",
"prepack": "backstage-cli package prepack",
"postpack": "backstage-cli package postpack",
"start": "backstage-cli package start",
"test": "backstage-cli package test"
},
"dependencies": {
"@backstage/backend-common": "workspace:^",
"@backstage/backend-test-utils": "workspace:^",
"@backstage/plugin-scaffolder-common": "workspace:^",
"@backstage/plugin-scaffolder-node": "workspace:^",
"@backstage/types": "workspace:^",
"winston": "^3.2.1"
},
"devDependencies": {
"@backstage/cli": "workspace:^",
"@testing-library/jest-dom": "^6.0.0",
"@types/react": "*"
}
}
@@ -0,0 +1,17 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export { createMockActionContext } from './mockActionConext';
@@ -0,0 +1,76 @@
/*
* Copyright 2023 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import { PassThrough, Writable } from 'stream';
import { getVoidLogger } from '@backstage/backend-common';
import { createMockDirectory } from '@backstage/backend-test-utils';
import { JsonObject } from '@backstage/types';
import { ActionContext, TaskSecrets } from '@backstage/plugin-scaffolder-node';
import * as winston from 'winston';
import { TemplateInfo } from '@backstage/plugin-scaffolder-common';
/**
* A utility method to create a mock action context for scaffolder actions.
*
* @public
* @param options - optional parameters to override default mock context
*/
export const createMockActionContext = <
TActionInput extends JsonObject = JsonObject,
TActionOutput extends JsonObject = JsonObject,
>(options?: {
input?: TActionInput;
logger?: winston.Logger;
logStream?: Writable;
secrets?: TaskSecrets;
templateInfo?: TemplateInfo;
workspacePath?: string;
}): ActionContext<TActionInput, TActionOutput> => {
const defaultContext = {
logger: getVoidLogger(),
logStream: new PassThrough(),
output: jest.fn(),
createTemporaryDirectory: jest.fn(),
input: {} as TActionInput,
};
const createDefaultWorkspace = () => ({
workspacePath: createMockDirectory().resolve('workspace'),
});
if (!options) {
return {
...defaultContext,
...createDefaultWorkspace(),
};
}
const { input, logger, logStream, secrets, templateInfo, workspacePath } =
options;
return {
...defaultContext,
...(workspacePath ? { workspacePath } : createDefaultWorkspace()),
...(workspacePath && {
createTemporaryDirectory: jest.fn().mockResolvedValue(workspacePath),
}),
...(logger && { logger }),
...(logStream && { logStream }),
...(input && { input }),
...(secrets && { secrets }),
templateInfo,
};
};
@@ -0,0 +1,17 @@
/*
* Copyright 2020 The Backstage Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
export * from './actions';
+30
View File
@@ -8209,6 +8209,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
azure-devops-node-api: ^12.0.0
yaml: ^2.0.0
languageName: unknown
@@ -8226,6 +8227,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
fs-extra: ^11.2.0
msw: ^1.0.0
node-fetch: ^2.6.7
@@ -8245,6 +8247,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
fs-extra: ^11.2.0
msw: ^1.0.0
node-fetch: ^2.6.7
@@ -8266,6 +8269,7 @@ __metadata:
"@backstage/plugin-scaffolder-backend-module-bitbucket-cloud": "workspace:^"
"@backstage/plugin-scaffolder-backend-module-bitbucket-server": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
fs-extra: ^11.2.0
msw: ^1.0.0
node-fetch: ^2.6.7
@@ -8285,6 +8289,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
fs-extra: ^11.2.0
git-url-parse: ^14.0.0
msw: ^1.0.0
@@ -8306,6 +8311,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@backstage/types": "workspace:^"
"@types/command-exists": ^1.2.0
"@types/fs-extra": ^11.0.0
@@ -8328,6 +8334,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
msw: ^1.0.0
node-fetch: ^2.6.7
yaml: ^2.0.0
@@ -8346,6 +8353,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
msw: ^1.0.0
node-fetch: ^2.6.7
yaml: ^2.0.0
@@ -8364,6 +8372,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@octokit/webhooks": ^10.0.0
"@types/libsodium-wrappers": ^0.7.10
fs-extra: ^11.2.0
@@ -8390,6 +8399,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@gitbeaker/core": ^35.8.0
"@gitbeaker/node": ^35.8.0
"@gitbeaker/rest": ^39.25.0
@@ -8412,6 +8422,7 @@ __metadata:
"@backstage/errors": "workspace:^"
"@backstage/integration": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@backstage/types": "workspace:^"
"@types/command-exists": ^1.2.0
"@types/fs-extra": ^11.0.0
@@ -8432,6 +8443,7 @@ __metadata:
"@backstage/config": "workspace:^"
"@backstage/errors": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@backstage/types": "workspace:^"
msw: ^2.0.0
yaml: ^2.3.3
@@ -8446,6 +8458,7 @@ __metadata:
"@backstage/backend-plugin-api": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@backstage/types": "workspace:^"
winston: ^3.2.1
yeoman-environment: ^3.9.1
@@ -8481,6 +8494,7 @@ __metadata:
"@backstage/plugin-scaffolder-backend-module-gitlab": "workspace:^"
"@backstage/plugin-scaffolder-common": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/plugin-scaffolder-node-test-utils": "workspace:^"
"@backstage/types": "workspace:^"
"@types/express": ^4.17.6
"@types/fs-extra": ^11.0.0
@@ -8525,6 +8539,22 @@ __metadata:
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-node-test-utils@workspace:^, @backstage/plugin-scaffolder-node-test-utils@workspace:plugins/scaffolder-node-test-utils":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-node-test-utils@workspace:plugins/scaffolder-node-test-utils"
dependencies:
"@backstage/backend-common": "workspace:^"
"@backstage/backend-test-utils": "workspace:^"
"@backstage/cli": "workspace:^"
"@backstage/plugin-scaffolder-common": "workspace:^"
"@backstage/plugin-scaffolder-node": "workspace:^"
"@backstage/types": "workspace:^"
"@testing-library/jest-dom": ^6.0.0
"@types/react": "*"
winston: ^3.2.1
languageName: unknown
linkType: soft
"@backstage/plugin-scaffolder-node@workspace:^, @backstage/plugin-scaffolder-node@workspace:plugins/scaffolder-node":
version: 0.0.0-use.local
resolution: "@backstage/plugin-scaffolder-node@workspace:plugins/scaffolder-node"