Skip to content

Commit

Permalink
🔧(prettier) add default rules (#1113)
Browse files Browse the repository at this point in the history
As it is recommended in python to respect a line width of 79 characters,
there are different recommendations in js. I suggest to use the Airbnb standard
which recommends to use 100 characters per line.
As prettier also format html files, we must ignore django templates files
because some syntax do not support line break
but prettier automatically break lines.
Launch prettier to apply new rules on frontend and website dirs

Co-authored-by: Jean-Baptiste PENRATH <[email protected]>
  • Loading branch information
jbpenrath and jbpenrath authored Sep 3, 2020
1 parent 6b33986 commit 7e2cfab
Show file tree
Hide file tree
Showing 87 changed files with 451 additions and 1,390 deletions.
3 changes: 3 additions & 0 deletions .prettierignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# Because django templates requires syntax which can't contain line break
# Prettier must ignore all Django templates files
src/richie/**/*.html
3 changes: 3 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
printWidth: 100
singleQuote: true
tabWidth: 2
trailingComma: all
useTabs: false
15 changes: 3 additions & 12 deletions src/frontend/js/common/searchFields/getSuggestionsSection.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,7 @@ describe('common/searchFields/getSuggestionsSection', () => {

let suggestionsSection;
try {
suggestionsSection = await getSuggestionsSection(
'courses',
'Courses',
'some search',
);
suggestionsSection = await getSuggestionsSection('courses', 'Courses', 'some search');
} catch (error) {
fail('Did not expect getSuggestionsSection to fail');
}
Expand All @@ -43,9 +39,7 @@ describe('common/searchFields/getSuggestionsSection', () => {
throws: new Error('Failed to send API request'),
});
await getSuggestionsSection('courses', 'Courses', 'some search');
expect(mockHandle).toHaveBeenCalledWith(
new Error('Failed to send API request'),
);
expect(mockHandle).toHaveBeenCalledWith(new Error('Failed to send API request'));
});

it('reports the error when the server returns an error code', async () => {
Expand All @@ -60,10 +54,7 @@ describe('common/searchFields/getSuggestionsSection', () => {
});

it('reports the error when it receives broken json', async () => {
fetchMock.get(
'/api/v1.0/courses/autocomplete/?query=some%20search',
'not json',
);
fetchMock.get('/api/v1.0/courses/autocomplete/?query=some%20search', 'not json');
await getSuggestionsSection('courses', 'Courses', 'some search');
expect(mockHandle).toHaveBeenCalledWith(
new Error(
Expand Down
27 changes: 7 additions & 20 deletions src/frontend/js/common/searchFields/getSuggestionsSection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,43 +12,30 @@ import { handle } from 'utils/errors/handle';
* @param sectionTitleMessage MessageDescriptor for the title of the section that displays the suggestions.
* @param query The actual payload to run the completion search with.
*/
export const getSuggestionsSection = async (
kind: string,
title: string,
query: string,
) => {
export const getSuggestionsSection = async (kind: string, title: string, query: string) => {
// Run the search for the section on the API
let response: Response;
try {
response = await fetch(
`/api/v1.0/${kind}/autocomplete/?${stringify({ query })}`,
{
headers: {
'Content-Type': 'application/json',
},
response = await fetch(`/api/v1.0/${kind}/autocomplete/?${stringify({ query })}`, {
headers: {
'Content-Type': 'application/json',
},
);
});
} catch (error) {
return handle(error);
}

// Fetch treats remote errors (400, 404, 503...) as successes
// The ok flag is the way to discriminate
if (!response.ok) {
return handle(
new Error(
`Failed to get list from ${kind} autocomplete : ${response.status}`,
),
);
return handle(new Error(`Failed to get list from ${kind} autocomplete : ${response.status}`));
}

let responseData: Suggestion<string>[];
try {
responseData = await response.json();
} catch (error) {
return handle(
new Error('Failed to decode JSON in getSuggestionSection ' + error),
);
return handle(new Error('Failed to decode JSON in getSuggestionSection ' + error));
}

return {
Expand Down
25 changes: 8 additions & 17 deletions src/frontend/js/common/searchFields/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,18 +14,17 @@ import { getSuggestionsSection } from './getSuggestionsSection';
* `react-autosuggest` callback to get a human string value from a Suggestion object.
* @param suggestion The relevant suggestion object.
*/
export const getSuggestionValue: SearchAutosuggestProps['getSuggestionValue'] = (
suggestion,
) => suggestion.title;
export const getSuggestionValue: SearchAutosuggestProps['getSuggestionValue'] = (suggestion) =>
suggestion.title;

/**
* `react-autosuggest` callback to render one suggestion.
* @param suggestion Either a resource suggestion with a model name & a machine name, or the default
* suggestion with some text to render.
*/
export const renderSuggestion: SearchAutosuggestProps['renderSuggestion'] = (
suggestion,
) => <span>{suggestion.title}</span>;
export const renderSuggestion: SearchAutosuggestProps['renderSuggestion'] = (suggestion) => (
<span>{suggestion.title}</span>
);

/**
* `react-autosuggest` callback to build up the list of suggestions and sections whenever user
Expand All @@ -50,11 +49,7 @@ export const onSuggestionsFetchRequested = async (
Object.values(await filters)
.filter((filterdef) => filterdef.is_autocompletable)
.map((filterdef) =>
getSuggestionsSection(
filterdef.name,
filterdef.human_name,
incomingValue,
),
getSuggestionsSection(filterdef.name, filterdef.human_name, incomingValue),
),
// We can assert this because of the catch below
)) as SearchSuggestionSection[];
Expand All @@ -78,19 +73,15 @@ export const getRelevantFilter = (
suggestion: SearchSuggestion,
) => {
// Use the `kind` field on the suggestion to pick the relevant filter to update.
let filter = Object.values(filters).find(
(fltr) => fltr.name === suggestion.kind,
)!;
let filter = Object.values(filters).find((fltr) => fltr.name === suggestion.kind)!;

// We need a special-case to handle categories until we refactor the API to separate endpoints between
// kinds of categories
if (!filter) {
// Pick the filter to update based on the payload's path: it contains the relevant filter's page path
// (for eg. a meta-category or the "organizations" root page)
filter = Object.values(filters).find(
(fltr) =>
!!fltr.base_path &&
String(suggestion.id).substr(2).startsWith(fltr.base_path),
(fltr) => !!fltr.base_path && String(suggestion.id).substr(2).startsWith(fltr.base_path),
)!;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,7 @@ import { Course } from 'types/Course';
* <CourseGlimpseFooter />.
* This is spun off from <CourseGlimpse /> to allow easier override through webpack.
*/
export const CourseGlimpseFooter: React.FC<
{ course: Course } & CommonDataProps
> = ({ course }) => {
export const CourseGlimpseFooter: React.FC<{ course: Course } & CommonDataProps> = ({ course }) => {
const intl = useIntl();
return (
<div className="course-glimpse-footer">
Expand Down
5 changes: 1 addition & 4 deletions src/frontend/js/components/CourseGlimpse/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,10 +91,7 @@ describe('components/CourseGlimpse', () => {
it('shows the "Cover" placeholder div when the course is missing a cover image', () => {
render(
<IntlProvider locale="en">
<CourseGlimpse
context={commonDataProps}
course={{ ...course, cover_image: null }}
/>
<CourseGlimpse context={commonDataProps} course={{ ...course, cover_image: null }} />
</IntlProvider>,
);

Expand Down
23 changes: 5 additions & 18 deletions src/frontend/js/components/CourseGlimpse/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,12 @@ export interface CourseGlimpseProps {
const messages = defineMessages({
cover: {
defaultMessage: 'Cover',
description:
'Placeholder text when the course we are glimpsing at is missing a cover image',
description: 'Placeholder text when the course we are glimpsing at is missing a cover image',
id: 'components.CourseGlimpse.cover',
},
});

const CourseGlimpseBase = ({
context,
course,
}: CourseGlimpseProps & CommonDataProps) => (
const CourseGlimpseBase = ({ context, course }: CourseGlimpseProps & CommonDataProps) => (
<a className="course-glimpse course-glimpse--link" href={course.absolute_url}>
<div className="course-glimpse__media">
{course.cover_image ? (
Expand All @@ -40,18 +36,10 @@ const CourseGlimpseBase = ({
<div className="course-glimpse__content">
{course.icon ? (
<div className="course-glimpse__icon">
<div
className="course-glimpse__band"
style={{ background: course.icon.color }}
>
<div className="course-glimpse__band" style={{ background: course.icon.color }}>
{course.icon.title}
</div>
<img
src={course.icon.src}
srcSet={course.icon.srcset}
sizes={course.icon.sizes}
alt=""
/>
<img src={course.icon.src} srcSet={course.icon.srcset} sizes={course.icon.sizes} alt="" />
</div>
) : null}
<div className="course-glimpse__wrapper">
Expand All @@ -72,7 +60,6 @@ const areEqual: (
prevProps: Readonly<CourseGlimpseProps & CommonDataProps>,
newProps: Readonly<CourseGlimpseProps & CommonDataProps>,
) => boolean = (prevProps, newProps) =>
prevProps.context === newProps.context &&
prevProps.course.id === newProps.course.id;
prevProps.context === newProps.context && prevProps.course.id === newProps.course.id;

export const CourseGlimpse = React.memo(CourseGlimpseBase, areEqual);
3 changes: 1 addition & 2 deletions src/frontend/js/components/CourseGlimpseList/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,7 @@ describe('components/CourseGlimpseList', () => {
);

expect(
screen.getAllByText('Showing 1 to 20 of 45 courses matching your search')
.length,
screen.getAllByText('Showing 1 to 20 of 45 courses matching your search').length,
).toEqual(1);
// Both courses' titles are shown
screen.getByText('Course 44');
Expand Down
5 changes: 1 addition & 4 deletions src/frontend/js/components/CourseGlimpseList/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,7 @@ export const CourseGlimpseList = ({
/>
</div>
{courses.map(
(course) =>
course && (
<CourseGlimpse context={context} course={course} key={course.id} />
),
(course) => course && <CourseGlimpse context={context} course={course} key={course.id} />,
)}
</div>
);
Expand Down
50 changes: 10 additions & 40 deletions src/frontend/js/components/CourseRunEnrollment/index.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,11 @@ describe('<CourseRunEnrollment />', () => {
courseRun.state.priority = 0;

const courseRunDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/course-runs/${courseRun.id}/`,
courseRunDeferred.promise,
);
fetchMock.get(`/api/v1.0/course-runs/${courseRun.id}/`, courseRunDeferred.promise);
const userDeferred = new Deferred();
fetchMock.get('/api/v1.0/users/whoami/', userDeferred.promise);
const enrollmentsDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/enrollments/?course_run=${courseRun.id}`,
enrollmentsDeferred.promise,
);
fetchMock.get(`/api/v1.0/enrollments/?course_run=${courseRun.id}`, enrollmentsDeferred.promise);

render(
<IntlProvider locale="en">
Expand Down Expand Up @@ -74,17 +68,11 @@ describe('<CourseRunEnrollment />', () => {
courseRun.state.priority = 0;

const courseRunDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/course-runs/${courseRun.id}/`,
courseRunDeferred.promise,
);
fetchMock.get(`/api/v1.0/course-runs/${courseRun.id}/`, courseRunDeferred.promise);
const userDeferred = new Deferred();
fetchMock.get('/api/v1.0/users/whoami/', userDeferred.promise);
const enrollmentsDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/enrollments/?course_run=${courseRun.id}`,
enrollmentsDeferred.promise,
);
fetchMock.get(`/api/v1.0/enrollments/?course_run=${courseRun.id}`, enrollmentsDeferred.promise);

render(
<IntlProvider locale="en">
Expand Down Expand Up @@ -122,17 +110,11 @@ describe('<CourseRunEnrollment />', () => {
courseRun.state.priority = 0;

const courseRunDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/course-runs/${courseRun.id}/`,
courseRunDeferred.promise,
);
fetchMock.get(`/api/v1.0/course-runs/${courseRun.id}/`, courseRunDeferred.promise);
const userDeferred = new Deferred();
fetchMock.get('/api/v1.0/users/whoami/', userDeferred.promise);
const enrollmentsDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/enrollments/?course_run=${courseRun.id}`,
enrollmentsDeferred.promise,
);
fetchMock.get(`/api/v1.0/enrollments/?course_run=${courseRun.id}`, enrollmentsDeferred.promise);

render(
<IntlProvider locale="en">
Expand Down Expand Up @@ -162,17 +144,11 @@ describe('<CourseRunEnrollment />', () => {
courseRun.state.priority = 4;

const courseRunDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/course-runs/${courseRun.id}/`,
courseRunDeferred.promise,
);
fetchMock.get(`/api/v1.0/course-runs/${courseRun.id}/`, courseRunDeferred.promise);
const userDeferred = new Deferred();
fetchMock.get('/api/v1.0/users/whoami/', userDeferred.promise);
const enrollmentsDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/enrollments/?course_run=${courseRun.id}`,
enrollmentsDeferred.promise,
);
fetchMock.get(`/api/v1.0/enrollments/?course_run=${courseRun.id}`, enrollmentsDeferred.promise);

render(
<IntlProvider locale="en">
Expand Down Expand Up @@ -200,15 +176,9 @@ describe('<CourseRunEnrollment />', () => {
courseRun.state.priority = 0;

const courseRunDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/course-runs/${courseRun.id}/`,
courseRunDeferred.promise,
);
fetchMock.get(`/api/v1.0/course-runs/${courseRun.id}/`, courseRunDeferred.promise);
const enrollmentsDeferred = new Deferred();
fetchMock.get(
`/api/v1.0/enrollments/?course_run=${courseRun.id}`,
enrollmentsDeferred.promise,
);
fetchMock.get(`/api/v1.0/enrollments/?course_run=${courseRun.id}`, enrollmentsDeferred.promise);
fetchMock.get('/api/v1.0/users/whoami/', 401);

render(
Expand Down
Loading

0 comments on commit 7e2cfab

Please sign in to comment.