Skip to content

Commit 85b0650

Browse files
authored
Merge pull request #2977 from RedisInsight/feature/RI-5116-limit-tutorials-links
#RI-5116 - limit tutorials links
2 parents 40016a8 + 422caa4 commit 85b0650

File tree

9 files changed

+47
-4
lines changed

9 files changed

+47
-4
lines changed

redisinsight/api/src/common/decorators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ export * from './client-metadata';
77
export * from './object-as-map.decorator';
88
export * from './is-multi-number.decorator';
99
export * from './is-bigger-than.decorator';
10+
export * from './is-github-link.decorator';
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import {
2+
registerDecorator,
3+
ValidationOptions,
4+
} from 'class-validator';
5+
import { GitHubLink } from 'src/common/validators';
6+
7+
export function IsGitHubLink(validationOptions?: ValidationOptions) {
8+
return (object: any, propertyName: string) => {
9+
registerDecorator({
10+
name: 'IsGitHubLink',
11+
target: object.constructor,
12+
propertyName,
13+
constraints: [],
14+
options: validationOptions,
15+
validator: GitHubLink,
16+
});
17+
};
18+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import {
2+
ValidatorConstraint,
3+
ValidatorConstraintInterface,
4+
} from 'class-validator';
5+
6+
@ValidatorConstraint({ name: 'GitHubLink', async: false })
7+
export class GitHubLink implements ValidatorConstraintInterface {
8+
validate(value: any) {
9+
// Regular expression to match any GitHub URL
10+
const githubUrlRegex = /^https:\/\/github\.com(?:\/[^\s/]+(?:\/[^\s/]+)*)?\/?$/;
11+
return typeof value === 'string' && githubUrlRegex.test(value);
12+
}
13+
14+
defaultMessage() {
15+
return 'Enter a full GitHub link';
16+
}
17+
}

redisinsight/api/src/common/validators/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ export * from './redis-string.validator';
22
export * from './zset-score.validator';
33
export * from './multi-number.validator';
44
export * from './bigger-than.validator';
5+
export * from './github-link.validator';

redisinsight/api/src/modules/custom-tutorial/dto/upload.custom-tutorial.dto.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { IsNotEmpty, IsOptional, IsString } from 'class-validator';
33
import {
44
HasMimeType, IsFile, MaxFileSize, MemoryStoredFile,
55
} from 'nestjs-form-data';
6+
import { IsGitHubLink } from 'src/common/decorators';
67

78
export class UploadCustomTutorialDto {
89
@ApiPropertyOptional({
@@ -23,5 +24,6 @@ export class UploadCustomTutorialDto {
2324
@IsOptional()
2425
@IsString()
2526
@IsNotEmpty()
27+
@IsGitHubLink()
2628
link?: string;
2729
}

redisinsight/api/test/api/custom-tutorials/POST-custom-tutorials.test.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ import {
99
path,
1010
serverConfig, requirements,
1111
before,
12+
nock,
1213
_,
1314
} from '../deps';
14-
import { getBaseURL } from '../../helpers/server';
1515
const { server, request, localDb } = deps;
1616

1717
// create endpoint
@@ -107,6 +107,8 @@ const globalManifest = {
107107
children: [],
108108
};
109109

110+
const nockScope = nock('https://github.com/somerepo');
111+
110112
describe('POST /custom-tutorials', () => {
111113
requirements('rte.serverType=local');
112114

@@ -197,7 +199,9 @@ describe('POST /custom-tutorials', () => {
197199

198200
it('should import tutorial from the external link with manifest', async () => {
199201
const zip = new AdmZip(path.join(staticsFolder, 'test.zip'));
200-
const link = `${getBaseURL()}/static/test.zip`;
202+
const file = await fsExtra.readFile(path.join(staticsFolder, 'test.zip'))
203+
nockScope.get('/test.zip').reply(200, file);
204+
const link = `https://github.com/somerepo/test.zip`;
201205

202206
await validateApiCall({
203207
endpoint: creatEndpoint,

redisinsight/ui/src/pages/workbench/components/enablement-area/EnablementArea/components/UploadTutorialForm/UploadTutorialForm.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ const UploadTutorialForm = (props: Props) => {
8585
</div>
8686
<div className={styles.hr}>OR</div>
8787
<EuiFieldText
88-
placeholder="Tutorial Link"
88+
placeholder="GitHub link to tutorials"
8989
value={formik.values.link}
9090
onChange={(e) => formik.setFieldValue('link', e.target.value)}
9191
className={styles.input}
452 KB
Binary file not shown.

tests/e2e/tests/web/regression/workbench/import-tutorials.e2e.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ test
114114
// https://redislabs.atlassian.net/browse/RI-4186, https://redislabs.atlassian.net/browse/RI-4213, https://redislabs.atlassian.net/browse/RI-4302
115115
test('Verify that user can upload tutorial with URL with manifest.json', async t => {
116116
const labelFromManifest = 'LabelFromManifest';
117-
const link = 'https://drive.google.com/uc?id=1puRUoT8HmyZCekkeWNxBzXe_48TzXcJc&export=download';
117+
const link = 'https://github.com/RedisInsight/RedisInsight/tree/main/tests/e2e/test-data/upload-tutorials/sample-manifest-link.zip';
118118
internalLinkName1 = 'manifest-id';
119119
tutorialName = 'tutorialTestByLink';
120120

0 commit comments

Comments
 (0)