Skip to content

Commit

Permalink
refactor: convert config actions to TypeScript (#4950)
Browse files Browse the repository at this point in the history
  • Loading branch information
Vladislav Shkodin authored Feb 14, 2021
1 parent 41e82c2 commit 0ac17bf
Show file tree
Hide file tree
Showing 6 changed files with 704 additions and 118 deletions.
3 changes: 2 additions & 1 deletion .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ module.exports = {
'require-atomic-updates': [0],
'import/no-unresolved': [0],
'@typescript-eslint/no-non-null-assertion': [0],
'@typescript-eslint/explicit-function-return-type': 0,
'@typescript-eslint/camelcase': [0],
'@typescript-eslint/explicit-function-return-type': [0],
'@typescript-eslint/no-use-before-define': [
'error',
{ functions: false, classes: true, variables: true },
Expand Down
52 changes: 50 additions & 2 deletions packages/netlify-cms-core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
declare module 'netlify-cms-core' {
import React, { ComponentType } from 'react';
import { List, Map } from 'immutable';
import { FILES, FOLDER } from '../constants/collectionTypes';

export type CmsBackendType =
| 'azure'
| 'git-gateway'
| 'github'
| 'gitlab'
| 'bitbucket'
| 'test-repo';
| 'test-repo'
| 'proxy';

export type CmsMapWidgetType = 'Point' | 'LineString' | 'Polygon';

Expand Down Expand Up @@ -62,7 +64,10 @@ declare module 'netlify-cms-core' {
required?: boolean;
hint?: string;
pattern?: [string, string];
i18n?: boolean | 'translate' | 'duplicate';
i18n?: boolean | 'translate' | 'duplicate' | 'none';
media_folder?: string;
public_folder?: string;
comment?: string;
}

export interface CmsFieldBoolean {
Expand Down Expand Up @@ -236,6 +241,15 @@ declare module 'netlify-cms-core' {
default?: string;
}

export interface CmsFieldMeta {
name: string;
label: string;
widget: string;
required: boolean;
index_file: string;
meta: boolean;
}

export type CmsField = CmsFieldBase &
(
| CmsFieldBoolean
Expand All @@ -252,6 +266,7 @@ declare module 'netlify-cms-core' {
| CmsFieldSelect
| CmsFieldHidden
| CmsFieldStringOrText
| CmsFieldMeta
);

export interface CmsCollectionFile {
Expand All @@ -261,6 +276,25 @@ declare module 'netlify-cms-core' {
fields: CmsField[];
label_singular?: string;
description?: string;
preview_path?: string;
preview_path_date_field?: string;
i18n?: boolean | CmsI18nConfig;
media_folder?: string;
public_folder?: string;
}

export interface ViewFilter {
label: string;
field: string;
pattern: string;
id: string;
}

export interface ViewGroup {
label: string;
field: string;
pattern: string;
id: string;
}

export interface CmsCollection {
Expand All @@ -280,6 +314,12 @@ declare module 'netlify-cms-core' {
editor?: {
preview?: boolean;
};
publish?: boolean;
nested?: {
depth: number;
};
type: typeof FOLDER | typeof FILES;
meta?: { path?: { label: string; widget: string; index_file: string } };

/**
* It accepts the following values: yml, yaml, toml, json, md, markdown, html
Expand All @@ -296,6 +336,8 @@ declare module 'netlify-cms-core' {
media_folder?: string;
public_folder?: string;
sortable_fields?: string[];
view_filters?: ViewFilter[];
view_groups?: ViewGroup[];
i18n?: boolean | CmsI18nConfig;

/**
Expand All @@ -316,11 +358,13 @@ declare module 'netlify-cms-core' {
auth_endpoint?: string;
cms_label_prefix?: string;
squash_merges?: boolean;
proxy_url?: string;
}

export interface CmsSlug {
encoding?: CmsSlugEncoding;
clean_accents?: boolean;
sanitize_replacement?: string;
}

export interface CmsLocalBackend {
Expand All @@ -341,9 +385,13 @@ declare module 'netlify-cms-core' {
media_folder_relative?: boolean;
media_library?: CmsMediaLibrary;
publish_mode?: CmsPublishMode;
load_config_file?: boolean;
slug?: CmsSlug;
i18n?: CmsI18nConfig;
local_backend?: boolean | CmsLocalBackend;
editor?: {
preview?: boolean;
};
}

export interface InitOptions {
Expand Down
89 changes: 89 additions & 0 deletions packages/netlify-cms-core/src/actions/__tests__/config.spec.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,24 @@
import { stripIndent } from 'common-tags';
import { fromJS } from 'immutable';
import {
loadConfig,
parseConfig,
normalizeConfig,
applyDefaults,
detectProxyServer,
handleLocalBackend,
} from '../config';

import yaml from 'js-yaml';

jest.spyOn(console, 'log').mockImplementation(() => {});
jest.spyOn(console, 'warn').mockImplementation(() => {});
jest.mock('../../backend', () => {
return {
resolveBackend: jest.fn(() => ({ isGitBackend: jest.fn(() => true) })),
};
});
jest.mock('../../constants/configSchema');

describe('config', () => {
describe('parseConfig', () => {
Expand Down Expand Up @@ -903,4 +908,88 @@ describe('config', () => {
});
});
});

describe('loadConfig', () => {
beforeEach(() => {
document.querySelector = jest.fn();
global.fetch = jest.fn();
});

test(`should fetch default 'config.yml'`, async () => {
const dispatch = jest.fn();

global.fetch.mockResolvedValue({
status: 200,
text: () => Promise.resolve(yaml.dump({ backend: { repo: 'test-repo' } })),
headers: new Headers(),
});
await loadConfig()(dispatch);

expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith('config.yml', { credentials: 'same-origin' });

expect(dispatch).toHaveBeenCalledTimes(2);
expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' });
expect(dispatch).toHaveBeenCalledWith({
type: 'CONFIG_SUCCESS',
payload: fromJS({
backend: { repo: 'test-repo' },
collections: [],
publish_mode: 'simple',
slug: { encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' },
public_folder: '/',
}),
});
});

test(`should fetch from custom 'config.yml'`, async () => {
const dispatch = jest.fn();

document.querySelector.mockReturnValue({ type: 'text/yaml', href: 'custom-config.yml' });
global.fetch.mockResolvedValue({
status: 200,
text: () => Promise.resolve(yaml.dump({ backend: { repo: 'github' } })),
headers: new Headers(),
});
await loadConfig()(dispatch);

expect(document.querySelector).toHaveBeenCalledTimes(1);
expect(document.querySelector).toHaveBeenCalledWith('link[rel="cms-config-url"]');

expect(global.fetch).toHaveBeenCalledTimes(1);
expect(global.fetch).toHaveBeenCalledWith('custom-config.yml', {
credentials: 'same-origin',
});

expect(dispatch).toHaveBeenCalledTimes(2);
expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' });
expect(dispatch).toHaveBeenCalledWith({
type: 'CONFIG_SUCCESS',
payload: fromJS({
backend: { repo: 'github' },
collections: [],
publish_mode: 'simple',
slug: { encoding: 'unicode', clean_accents: false, sanitize_replacement: '-' },
public_folder: '/',
}),
});
});

test(`should throw on failure to fetch 'config.yml'`, async () => {
const dispatch = jest.fn();

global.fetch.mockRejectedValue(new Error('Failed to fetch'));
await expect(() => loadConfig()(dispatch)).rejects.toEqual(
new Error('Failed to load config.yml (Failed to fetch)'),
);

expect(dispatch).toHaveBeenCalledTimes(2);
expect(dispatch).toHaveBeenCalledWith({ type: 'CONFIG_REQUEST' });
expect(dispatch).toHaveBeenCalledWith({
type: 'CONFIG_FAILURE',
error: 'Error loading config',
payload: new Error('Failed to load config.yml (Failed to fetch)'),
});
});
});
});
Loading

0 comments on commit 0ac17bf

Please sign in to comment.