Skip to content

Commit

Permalink
Feature: ABNF validation (#2044)
Browse files Browse the repository at this point in the history
  • Loading branch information
thewahome authored Oct 12, 2022
1 parent 2f1106a commit 0cedb2a
Show file tree
Hide file tree
Showing 13 changed files with 2,331 additions and 42 deletions.
2 changes: 1 addition & 1 deletion config/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ module.exports = function (webpackEnv) {
// public/ and not a SPA route
new RegExp('/[^/]+\\.[^/]+$')
],
maximumFileSizeToCacheInBytes: 6 * 1024 * 1024
maximumFileSizeToCacheInBytes: 10 * 1024 * 1024
}),
// TypeScript type checking
useTypeScript &&
Expand Down
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@ms-ofb/officebrowserfeedbacknpm": "file:packages/officebrowserfeedbacknpm-1.6.6.tgz",
"adaptivecards": "2.11.1",
"adaptivecards-templating": "1.4.0",
"apg-js": "4.1.2",
"babel-loader": "8.2.5",
"babel-preset-react-app": "10.0.1",
"bfj": "7.0.2",
Expand Down Expand Up @@ -131,4 +132,4 @@
"resolutions": {
"@types/react": "17.0.30"
}
}
}
25 changes: 1 addition & 24 deletions src/app/utils/sample-url-generation.spec.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { hasWhiteSpace, parseSampleUrl } from './sample-url-generation';
import { parseSampleUrl } from './sample-url-generation';

describe('Sample Url Generation', () => {

Expand Down Expand Up @@ -95,26 +95,3 @@ describe('Sample Url Generation', () => {
});

});


describe('hasWhiteSpaces should', () => {
const invalidUrls = [
{ url: ' https://graph.microsoft.com/v1.0/me', output: false },
{ url: 'https: //graph.microsoft.com/v1.0/me', output: true },
{ url: 'https://%20graph.microsoft.com/v1.0/me', output: true },
{ url: 'https://graph.microsoft.com/ v1.0/me', output: true },
{ url: 'https://graph.microsoft.com/v1.0/ me', output: true },
{
url:
'https://graph.microsoft.com/v1.0/me/contacts?$filter=emailAddresses/any(a:a/address eq \'[email protected]\')',
output: false
},
{ url: 'https://graph.microsoft.com/v1.0/me ', output: false }
];
invalidUrls.forEach(invalidUrl => {
it(`validate whitespaces in the url: ${invalidUrl.url}`, () => {
expect(hasWhiteSpace(invalidUrl.url)).toBe(invalidUrl.output);
});
});
});

7 changes: 0 additions & 7 deletions src/app/utils/sample-url-generation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,6 @@ export function removeExtraSlashesFromUrl(url: string): string {
return url.replace(/([^:]\/)\/+/g, '$1');
}

export function hasWhiteSpace(url: string): boolean {
const whitespaceChars = [' ', '\t', '\n', '%20'];
const parts = url.split('?');
return parts.length > 1 ? whitespaceChars.some((char) => parts[0].trimStart().includes(char)) :
whitespaceChars.some((char) => parts[0].trim().includes(char));
}

export function hasPlaceHolders(url: string): boolean {
const placeHolderChars = ['{', '}'];
return placeHolderChars.length > 1 && placeHolderChars.every((char) => url.includes(char));
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getTheme, KeyCodes, TextField } from '@fluentui/react';
import { getTheme, KeyCodes, TextField, Text, ITextFieldProps } from '@fluentui/react';
import React, { useEffect, useRef, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';

Expand Down Expand Up @@ -27,7 +27,7 @@ const AutoComplete = (props: IAutoCompleteProps) => {

let element: HTMLDivElement | null | undefined = null;

const { sampleQuery, autoComplete: { data: autoCompleteOptions } } = useSelector(
const { sampleQuery, autoComplete: { data: autoCompleteOptions, pending: autoCompletePending } } = useSelector(
(state: IRootState) => state
);

Expand Down Expand Up @@ -243,6 +243,17 @@ const AutoComplete = (props: IAutoCompleteProps) => {
input: autoInput
}: any = queryInputStyles(currentTheme).autoComplete;

const handleRenderDescription = (properties?: ITextFieldProps): JSX.Element | null => {
if (!shouldShowSuggestions && !autoCompletePending && properties?.description) {
return (
<Text variant="small" >
{properties?.description}
</Text>
);
}
return null;
};


return (
<div onBlur={closeSuggestionDialog}>
Expand All @@ -262,7 +273,8 @@ const AutoComplete = (props: IAutoCompleteProps) => {
onRenderSuffix={(renderSuffix()) ? renderSuffix : undefined}
ariaLabel={translateMessage('Query Sample Input')}
role='textbox'
errorMessage={getErrorMessage(queryUrl)}
onRenderDescription={handleRenderDescription}
description={getErrorMessage(queryUrl)}
/>
</div>
{shouldShowSuggestions && queryUrl && suggestions.length > 0 &&
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { hasPlaceHolders, hasWhiteSpace } from '../../../../utils/sample-url-generation';
import { ValidatedUrl } from '../../../../../modules/validation/abnf';
import { hasPlaceHolders } from '../../../../utils/sample-url-generation';
import { translateMessage } from '../../../../utils/translate-messages';

function cleanUpSelectedSuggestion(compare: string, userInput: string, selected: string) {
Expand Down Expand Up @@ -41,15 +42,27 @@ function getErrorMessage(queryUrl: string) {
if (!queryUrl) {
return translateMessage('Missing url');
}
if (hasWhiteSpace(queryUrl)) {
return translateMessage('Invalid whitespace in URL');
}

if (hasPlaceHolders(queryUrl)) {
return translateMessage('Parts between {} need to be replaced with real values');
}

const error = getValidationError(queryUrl);
if (error) {
return `${translateMessage('Possible error found in URL near')}: ${error}`;
}
return '';
}

function getValidationError(queryUrl: string): string | null {
const validator = new ValidatedUrl();
const validation = validator.validate(queryUrl);
if (!validation.success) {
return queryUrl.substring(validation.matched, validation.maxMatched);
}
return null;
}

function getSearchText(input: string, index: number) {
const stringPosition = index + 1;
const previous = input.substring(0, stringPosition);
Expand Down
3 changes: 2 additions & 1 deletion src/messages/GE.json
Original file line number Diff line number Diff line change
Expand Up @@ -450,5 +450,6 @@
"Parts between {} need to be replaced with real values": "Parts between {} need to be replaced with real values",
"Get started with Graph Explorer": "Get started with Graph Explorer",
"No resources found": "We did not find any resource items",
"No samples found": "We did not find any sample queries"
"No samples found": "We did not find any sample queries",
"Possible error found in URL near": "Possible error found in URL near"
}
Loading

0 comments on commit 0cedb2a

Please sign in to comment.