Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

(chore) Dependency upgrades and improvements to linting and types #190

Merged
merged 8 commits into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from 2 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
1 change: 1 addition & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
e2e/**
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't the tests themselves be linted?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, they should. I forgot to restore this.

src/**/*.test.tsx
**/*.d.tsx
35 changes: 29 additions & 6 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -1,16 +1,39 @@
{
"parser": "@typescript-eslint/parser",
"plugins": [
"@typescript-eslint"
],
"root": true,
"env": {
"node": true
},
"extends": [
"eslint:recommended",
"plugin:prettier/recommended",
"plugin:@typescript-eslint/recommended",
"ts-react-important-stuff"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1

"plugin:@typescript-eslint/recommended-requiring-type-checking"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"project": true,
"tsconfigRootDir": "__dirname"
},
"plugins": ["@typescript-eslint"],
"root": true,
"rules": {
"@typescript-eslint/no-unsafe-assignment": "off",
"@typescript-eslint/no-unsafe-call": "off",
"@typescript-eslint/no-unsafe-member-access": "off",
"@typescript-eslint/unbound-method": "off",
"@typescript-eslint/consistent-type-exports": "error",
"@typescript-eslint/consistent-type-imports": [
"error",
{
"prefer": "type-imports",
"disallowTypeAnnotations": true
}
],
"@typescript-eslint/array-type": [
"error",
{
"default": "generic"
}
],
"no-restricted-imports": [
"error",
{
Expand Down
4 changes: 3 additions & 1 deletion .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

yarn pretty-quick --staged
npx lint-staged
yarn turbo extract-translations

8 changes: 8 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"bracketSpacing": true,
"printWidth": 80,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't we usually use 120?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah. I'll switch back to that.

"semi": true,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "all"
}
60 changes: 43 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ The Form Builder is a widget used to create OpenMRS form schemas. It enables use

## Form Builder User Guide

* See the thorough User Guide for the Form Builder here: https://ampath-forms.vercel.app/docs/quickstart
* Prerequisites & dependencies are covered here: https://ampath-forms.vercel.app/docs/developer-guide/run-form-engine-in-openmrs3#prerequisites
* See the thorough User Guide for the Form Builder here: <https://ampath-forms.vercel.app/docs/quickstart>
* Prerequisites & dependencies are covered here: <https://ampath-forms.vercel.app/docs/developer-guide/run-form-engine-in-openmrs3#prerequisites>

## Running this code

Under the hood, the Form Builder uses the [OHRI form engine](https://www.npmjs.com/package/@openmrs/openmrs-form-engine-lib) to render a visual representation of your schema. This visual preview gets progressively updated as you build your schema. When done building, you can save your schema to an OpenMRS server. You can also publish your schema to make it available to your frontend.

To set up environment variables for the project, follow these steps:

1. Create a copy of the .env.example file by running the following command:

```bash
cp example.env .env
```
```bash
cp example.env .env
```

2. Open the newly created .env file in the root of the project.

Expand All @@ -35,17 +36,49 @@ yarn start # Launches a dev server

Once the dev server launches, log in and select a location. You will get redirected to the home page. Once there, you can either:

- Click the App Switcher icon in the top right corner and then click `Form Builder` to launch the app.
- Manually navigate to the `/openmrs/spa/form-builder` URL.
* Click the App Switcher icon in the top right corner and then click the `System Administration` link to go the Admin page. Click on the `Form Builder` tile to launch the app.
* Manually navigate to the `/openmrs/spa/form-builder` URL.

## Running tests

### Unit tests

To run unit tests, use:
To run tests for all packages, run:

```sh
yarn test
```bash
yarn turbo test
```

To run tests in `watch` mode, run:

```bash
yarn turbo test:watch
```

To run a specific test file, run:

```bash
yarn turbo test -- dashboard
```

The above command will only run tests in the file or files that match the provided string.

You can also run the matching tests from above in watch mode by running:

```bash
yarn turbo test:watch -- dashboard
```

To generate a `coverage` report, run:

```bash
yarn turbo coverage
```

By default, `turbo` will cache test runs. This means that re-running tests wihout changing any of the related files will return the cached logs from the last run. To bypass the cache, run tests with the `force` flag, as follows:

```bash
yarn turbo test --force
```

### E2E tests
Expand All @@ -64,15 +97,8 @@ yarn test-e2e --headed

Please read [our e2e docs](e2e/README.md) for more information about E2E testing.


## Building

```sh
yarn build
```

## Running tests

```sh
yarn test
```
14 changes: 7 additions & 7 deletions __mocks__/react-i18next.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/** At present, this entire mock is boilerplate. */

const React = require("react");
const reactI18next = require("react-i18next");
const React = require('react');
const reactI18next = require('react-i18next');

const hasChildren = (node) =>
node && (node.children || (node.props && node.props.children));
Expand All @@ -10,25 +10,25 @@ const getChildren = (node) =>
node && node.children ? node.children : node.props && node.props.children;

const renderNodes = (reactNodes) => {
if (typeof reactNodes === "string") {
if (typeof reactNodes === 'string') {
return reactNodes;
}

return Object.keys(reactNodes).map((key, i) => {
const child = reactNodes[key];
const isElement = React.isValidElement(child);

if (typeof child === "string") {
if (typeof child === 'string') {
return child;
}
if (hasChildren(child)) {
const inner = renderNodes(getChildren(child));
return React.cloneElement(child, { ...child.props, key: i }, inner);
}
if (typeof child === "object" && !isElement) {
if (typeof child === 'object' && !isElement) {
return Object.keys(child).reduce(
(str, childKey) => `${str}${child[childKey]}`,
""
'',
);
}

Expand All @@ -37,7 +37,7 @@ const renderNodes = (reactNodes) => {
};

const useMock = [(k) => k, {}];
useMock.t = (k, o) => (o && o.defaultValue) || (typeof o === "string" ? o : k);
useMock.t = (k, o) => (o && o.defaultValue) || (typeof o === 'string' ? o : k);
useMock.i18n = {};

module.exports = {
Expand Down
33 changes: 17 additions & 16 deletions e2e/commands/form-operations.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,19 @@
import { APIRequestContext, expect } from "@playwright/test";
import customSchema from "../support/custom-schema.json";
import type { APIRequestContext } from '@playwright/test';
import { expect } from '@playwright/test';
import customSchema from '../support/custom-schema.json';

export const createForm = async (
api: APIRequestContext,
isFormPublished: boolean
isFormPublished: boolean,
) => {
const formResponse = await api.post("form", {
const formResponse = await api.post('form', {
data: {
name: `A sample test form ${Math.floor(Math.random() * 10000)}`,
version: "1.0",
version: '1.0',
published: isFormPublished,
description: "This is the form description",
description: 'This is the form description',
encounterType: {
uuid: "e22e39fd-7db2-45e7-80f1-60fa0d5a4378",
uuid: 'e22e39fd-7db2-45e7-80f1-60fa0d5a4378',
},
},
});
Expand All @@ -25,12 +26,12 @@ export const createForm = async (
export const addFormResources = async (
api: APIRequestContext,
valueReference: string,
formUuid: string
formUuid: string,
) => {
const formResourcesRes = await api.post(`form/${formUuid}/resource`, {
data: {
name: "JSON schema",
dataType: "AmpathJsonSchema",
name: 'JSON schema',
dataType: 'AmpathJsonSchema',
valueReference: valueReference,
},
});
Expand All @@ -39,21 +40,21 @@ export const addFormResources = async (

export const createValueReference = async (api: APIRequestContext) => {
const boundary =
"--------------------------" + Math.floor(Math.random() * 1e16);
const delimiter = "\r\n--" + boundary + "\r\n";
const closeDelimiter = "\r\n--" + boundary + "--";
'--------------------------' + Math.floor(Math.random() * 1e16);
const delimiter = '\r\n--' + boundary + '\r\n';
const closeDelimiter = '\r\n--' + boundary + '--';

const body =
delimiter +
'Content-Disposition: form-data; name="file"; filename="schema.json"\r\n' +
"Content-Type: application/json\r\n\r\n" +
'Content-Type: application/json\r\n\r\n' +
JSON.stringify(customSchema) +
closeDelimiter;

const valueReference = await api.post("clobdata", {
const valueReference = await api.post('clobdata', {
data: body,
headers: {
"Content-Type": "multipart/form-data; boundary=" + boundary,
'Content-Type': 'multipart/form-data; boundary=' + boundary,
},
});
await expect(valueReference.ok()).toBeTruthy();
Expand Down
14 changes: 7 additions & 7 deletions e2e/core/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { request } from "@playwright/test";
import * as dotenv from "dotenv";
import { request } from '@playwright/test';
import * as dotenv from 'dotenv';

dotenv.config();

Expand All @@ -13,19 +13,19 @@ dotenv.config();
async function globalSetup() {
const requestContext = await request.newContext();
const token = Buffer.from(
`${process.env.E2E_USER_ADMIN_USERNAME}:${process.env.E2E_USER_ADMIN_PASSWORD}`
).toString("base64");
`${process.env.E2E_USER_ADMIN_USERNAME}:${process.env.E2E_USER_ADMIN_PASSWORD}`,
).toString('base64');
await requestContext.post(`${process.env.E2E_BASE_URL}/ws/rest/v1/session`, {
data: {
sessionLocation: process.env.E2E_LOGIN_DEFAULT_LOCATION_UUID,
locale: "en",
locale: 'en',
},
headers: {
"Content-Type": "application/json",
'Content-Type': 'application/json',
Authorization: `Basic ${token}`,
},
});
await requestContext.storageState({ path: "e2e/storageState.json" });
await requestContext.storageState({ path: 'e2e/storageState.json' });
await requestContext.dispose();
}

Expand Down
2 changes: 1 addition & 1 deletion e2e/core/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./test";
export * from './test';
6 changes: 3 additions & 3 deletions e2e/core/test.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { APIRequestContext, Page, test as base } from "@playwright/test";
import { api } from "../fixtures";
import { APIRequestContext, Page, test as base } from '@playwright/test';
import { api } from '../fixtures';

// This file sets up our custom test harness using the custom fixtures.
// See https://playwright.dev/docs/test-fixtures#creating-a-fixture for details.
Expand All @@ -16,5 +16,5 @@ export interface CustomWorkerFixtures {
}

export const test = base.extend<CustomTestFixtures, CustomWorkerFixtures>({
api: [api, { scope: "worker" }],
api: [api, { scope: 'worker' }],
});
4 changes: 2 additions & 2 deletions e2e/fixtures/api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import {
import type {
APIRequestContext,
PlaywrightWorkerArgs,
WorkerFixture,
} from "@playwright/test";
} from '@playwright/test';

/**
* A fixture which initializes an [`APIRequestContext`](https://playwright.dev/docs/api/class-apirequestcontext)
Expand Down
2 changes: 1 addition & 1 deletion e2e/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from "./api";
export * from './api';
Loading
Loading