Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { render, screen } from '@testing-library/react';
import { Form } from 'antd';
import React from 'react';

import { FieldType, GIT_INFO_REPO } from '@app/ingestV2/source/builder/RecipeForm/common';

// Mock FormField component for testing
const MockFormField = ({ field, removeMargin: _removeMargin }: { field: any; removeMargin: boolean }) => {
const { name, label, tooltip, type, placeholder, rules, required } = field;

return (
<div data-testid={`form-field-${name}`}>
<label htmlFor={`input-${name}`}>{label}</label>
{tooltip && (
<div data-testid={`tooltip-${name}`}>{typeof tooltip === 'string' ? tooltip : 'React tooltip'}</div>
)}
<input
id={`input-${name}`}
type={type === FieldType.SECRET ? 'password' : 'text'}
placeholder={placeholder}
data-required={required}
data-rules={rules ? rules.length : 0}
/>
</div>
);
};

describe('Common Git Info Fields', () => {
describe('GIT_INFO_REPO', () => {
it('should have correct field properties', () => {
expect(GIT_INFO_REPO.name).toBe('git_info.repo');
expect(GIT_INFO_REPO.label).toBe('Git Repository');
expect(GIT_INFO_REPO.type).toBe(FieldType.TEXT);
expect(GIT_INFO_REPO.fieldPath).toBe('source.config.git_info.repo');
expect(GIT_INFO_REPO.rules).toBeNull();
});

it('should not be required by default', () => {
expect(GIT_INFO_REPO.required).toBeUndefined();
});

it('should render tooltip with multi-platform examples', () => {
render(
<Form>
<MockFormField field={GIT_INFO_REPO} removeMargin={false} />,
</Form>,
);

const tooltip = screen.getByTestId('tooltip-git_info.repo');
expect(tooltip.textContent).toContain('React tooltip');
});

it('should have updated from deprecated github_info', () => {
expect(GIT_INFO_REPO.name).not.toContain('github_info');
expect(GIT_INFO_REPO.name).toContain('git_info');
expect(GIT_INFO_REPO.label).not.toBe('GitHub Repo');
expect(GIT_INFO_REPO.label).toBe('Git Repository');
});

it('should support multiple Git platforms in tooltip', () => {
// Test that the tooltip contains information about multiple platforms
const { tooltip } = GIT_INFO_REPO;
expect(tooltip).toBeDefined();

// Since tooltip is a React component, we test its structure
expect(React.isValidElement(tooltip)).toBe(true);
});
});

describe('Field Configuration', () => {
it('should have correct field path structure', () => {
expect(GIT_INFO_REPO.fieldPath).toBe('source.config.git_info.repo');
expect(GIT_INFO_REPO.fieldPath).toMatch(/^source\.config\.git_info\./);
});

it('should be a text input field', () => {
expect(GIT_INFO_REPO.type).toBe(FieldType.TEXT);
});

it('should not have validation rules', () => {
expect(GIT_INFO_REPO.rules).toBeNull();
});
});

describe('Multi-Platform Support', () => {
it('should have tooltip that mentions multiple platforms', () => {
// The tooltip should be a React component that includes examples
// for different Git platforms
expect(GIT_INFO_REPO.tooltip).toBeDefined();
expect(React.isValidElement(GIT_INFO_REPO.tooltip)).toBe(true);
});

it('should support flexible repository URL formats', () => {
// The field should accept various repository URL formats
// This is tested by the fact that there are no strict validation rules
expect(GIT_INFO_REPO.rules).toBeNull();
});
});

describe('Backward Compatibility', () => {
it('should replace deprecated github_info field', () => {
// Ensure the field name has been updated from github_info to git_info
expect(GIT_INFO_REPO.name).toBe('git_info.repo');
expect(GIT_INFO_REPO.name).not.toBe('github_info.repo');
});

it('should have updated label from GitHub-specific to generic', () => {
expect(GIT_INFO_REPO.label).toBe('Git Repository');
expect(GIT_INFO_REPO.label).not.toBe('GitHub Repo');
});

it('should have updated field path', () => {
expect(GIT_INFO_REPO.fieldPath).toBe('source.config.git_info.repo');
expect(GIT_INFO_REPO.fieldPath).not.toBe('source.config.github_info.repo');
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { GIT_INFO_REPO } from '@app/ingestV2/source/builder/RecipeForm/common';
import { RECIPE_FIELDS } from '@app/ingestV2/source/builder/RecipeForm/constants';
import { LOOKML, LOOKML_GIT_INFO_REPO } from '@app/ingestV2/source/builder/RecipeForm/lookml';

describe('Constants Git Info Integration', () => {
describe('Field Imports', () => {
it('should import LOOKML_GIT_INFO_REPO from lookml module', () => {
expect(LOOKML_GIT_INFO_REPO).toBeDefined();
expect(LOOKML_GIT_INFO_REPO.name).toBe('git_info.repo');
});

it('should import GIT_INFO_REPO from common module', () => {
expect(GIT_INFO_REPO).toBeDefined();
expect(GIT_INFO_REPO.name).toBe('git_info.repo');
});
});

describe('Source Configuration Integration', () => {
it('should include LOOKML_GIT_INFO_REPO in LOOKML source config', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
expect(lookmlConfig).toBeDefined();
expect(lookmlConfig.fields).toContain(LOOKML_GIT_INFO_REPO);
});

it('should have correct field order in LOOKML config', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

// LOOKML_GIT_INFO_REPO should be the first field
expect(fields[0]).toBe(LOOKML_GIT_INFO_REPO);
});

it('should not contain deprecated github_info references', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

// Check that no fields have github_info in their name
const githubInfoFields = fields.filter((field) => field.name && field.name.includes('github_info'));
expect(githubInfoFields).toHaveLength(0);
});

it('should contain git_info references', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

// Check that fields have git_info in their name
const gitInfoFields = fields.filter((field) => field.name && field.name.includes('git_info'));
expect(gitInfoFields.length).toBeGreaterThan(0);
});
});

describe('Field Consistency', () => {
it('should have consistent field paths for git_info', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

const gitInfoFields = fields.filter((field) => field.name && field.name.includes('git_info'));

gitInfoFields.forEach((field) => {
expect(field.fieldPath).toMatch(/^source\.config\.git_info\./);
});
});

it('should have proper field types for git_info fields', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

const gitInfoFields = fields.filter((field) => field.name && field.name.includes('git_info'));

gitInfoFields.forEach((field) => {
expect(field.type).toBeDefined();
expect(['TEXT', 'SECRET']).toContain(field.type);

Check failure on line 72 in datahub-web-react/src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx

View workflow job for this annotation

GitHub Actions / build (frontend, UTC)

src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx > Constants Git Info Integration > Field Consistency > should have proper field types for git_info fields

AssertionError: expected [ 'TEXT', 'SECRET' ] to include +0 ❯ forEach src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx:72:44 ❯ src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx:70:27

Check failure on line 72 in datahub-web-react/src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx

View workflow job for this annotation

GitHub Actions / build (frontend, America/New_York)

src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx > Constants Git Info Integration > Field Consistency > should have proper field types for git_info fields

AssertionError: expected [ 'TEXT', 'SECRET' ] to include +0 ❯ forEach src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx:72:44 ❯ src/app/ingestV2/source/builder/RecipeForm/__tests__/constants-git-info.test.tsx:70:27
});
});
});

describe('Migration from github_info', () => {
it('should not have any github_info field references', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

// Ensure no fields reference the old github_info structure
const oldFieldPaths = fields.filter((field) => field.fieldPath && field.fieldPath.includes('github_info'));
expect(oldFieldPaths).toHaveLength(0);
});

it('should have updated field names from github_info to git_info', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

const gitInfoFields = fields.filter((field) => field.name && field.name.includes('git_info'));

expect(gitInfoFields.length).toBeGreaterThan(0);

gitInfoFields.forEach((field) => {
expect(field.name).toMatch(/^git_info\./);
expect(field.name).not.toMatch(/^github_info\./);
});
});
});

describe('Field Validation', () => {
it('should have required fields properly marked', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

const requiredFields = fields.filter((field) => field.required === true);
expect(requiredFields.length).toBeGreaterThan(0);
});

it('should have validation rules for required fields', () => {
const lookmlConfig = RECIPE_FIELDS[LOOKML];
const { fields } = lookmlConfig;

const fieldsWithRules = fields.filter((field) => field.rules && field.rules.length > 0);

expect(fieldsWithRules.length).toBeGreaterThan(0);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
import { LOOKML_GIT_INFO_REPO_SSH_LOCATOR } from '@app/ingestV2/source/builder/RecipeForm/lookml';

describe('Git Info Validation Logic', () => {
const createValidator = (repoValue: string | undefined | null) => {
return LOOKML_GIT_INFO_REPO_SSH_LOCATOR.rules![0]({
getFieldValue: (fieldName) => {
if (fieldName === 'git_info.repo') return repoValue;
return undefined;
},
});
};

describe('REPO_SSH_LOCATOR Validation', () => {
describe('GitHub Repository Detection', () => {
it('should not require SSH locator for GitHub short format', async () => {
const validator = createValidator('datahub-project/datahub');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator for GitHub full URL', async () => {
const validator = createValidator('https://github.com/datahub-project/datahub');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator for GitHub URL without protocol', async () => {
const validator = createValidator('github.com/datahub-project/datahub');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator for GitHub URL with trailing slash', async () => {
const validator = createValidator('https://github.com/datahub-project/datahub/');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});
});

describe('GitLab Repository Detection', () => {
it('should not require SSH locator for GitLab full URL', async () => {
const validator = createValidator('https://gitlab.com/gitlab-org/gitlab');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator for GitLab URL without protocol', async () => {
const validator = createValidator('gitlab.com/gitlab-org/gitlab');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator for GitLab URL with trailing slash', async () => {
const validator = createValidator('https://gitlab.com/gitlab-org/gitlab/');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});
});

describe('Other Git Platforms', () => {
it('should require SSH locator for Bitbucket', async () => {
const validator = createValidator('https://bitbucket.org/org/repo');
await expect(validator.validator({}, '')).rejects.toThrow(
'Repository SSH Locator is required for Git platforms other than GitHub and GitLab',
);
});

it('should require SSH locator for custom Git server', async () => {
const validator = createValidator('https://custom-git.com/org/repo');
await expect(validator.validator({}, '')).rejects.toThrow(
'Repository SSH Locator is required for Git platforms other than GitHub and GitLab',
);
});

it('should require SSH locator for SSH URL format', async () => {
const validator = createValidator('[email protected]:org/repo');
await expect(validator.validator({}, '')).rejects.toThrow(

Check failure on line 70 in datahub-web-react/src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx

View workflow job for this annotation

GitHub Actions / build (frontend, UTC)

src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx > Git Info Validation Logic > REPO_SSH_LOCATOR Validation > Other Git Platforms > should require SSH locator for SSH URL format

AssertionError: promise resolved "undefined" instead of rejecting - Expected: Error { "message": "rejected promise", } + Received: undefined ❯ src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx:70:54

Check failure on line 70 in datahub-web-react/src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx

View workflow job for this annotation

GitHub Actions / build (frontend, America/New_York)

src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx > Git Info Validation Logic > REPO_SSH_LOCATOR Validation > Other Git Platforms > should require SSH locator for SSH URL format

AssertionError: promise resolved "undefined" instead of rejecting - Expected: Error { "message": "rejected promise", } + Received: undefined ❯ src/app/ingestV2/source/builder/RecipeForm/__tests__/git-info-validation.test.tsx:70:54
'Repository SSH Locator is required for Git platforms other than GitHub and GitLab',
);
});

it('should not require SSH locator when SSH locator is provided', async () => {
const validator = createValidator('https://custom-git.com/org/repo');
await expect(validator.validator({}, '[email protected]:org/repo.git')).resolves.toBeUndefined();
});
});

describe('Edge Cases', () => {
it('should not require SSH locator when repo is undefined', async () => {
const validator = createValidator(undefined);
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator when repo is null', async () => {
const validator = createValidator(null);
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should not require SSH locator when repo is empty string', async () => {
const validator = createValidator('');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should handle case-insensitive GitHub detection', async () => {
const validator = createValidator('https://GITHUB.COM/datahub-project/datahub');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should handle case-insensitive GitLab detection', async () => {
const validator = createValidator('https://GITLAB.COM/gitlab-org/gitlab');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});
});

describe('Complex Repository URLs', () => {
it('should handle GitHub URLs with additional path segments', async () => {
const validator = createValidator('https://github.com/datahub-project/datahub/tree/main/src');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should handle GitLab URLs with additional path segments', async () => {
const validator = createValidator('https://gitlab.com/gitlab-org/gitlab/-/tree/main/src');
await expect(validator.validator({}, '')).resolves.toBeUndefined();
});

it('should require SSH locator for non-GitHub/GitLab URLs with similar patterns', async () => {
const validator = createValidator('https://github-enterprise.company.com/org/repo');
await expect(validator.validator({}, '')).rejects.toThrow(
'Repository SSH Locator is required for Git platforms other than GitHub and GitLab',
);
});
});
});

describe('Validation Error Messages', () => {
it('should provide clear error message for missing SSH locator', async () => {
const validator = createValidator('https://custom-git.com/org/repo');
try {
await validator.validator({}, '');
} catch (error: any) {
expect(error.message).toBe(
'Repository SSH Locator is required for Git platforms other than GitHub and GitLab',
);
}
});
});
});
Loading
Loading