Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,32 @@ Para desmontar o `iframe` da DOM:
transaction.unmount();
```

### Click Forms (`v3-beta`)

Para criar o componente de form:

```javascript
import Form from '@clicksign/embedded/v3/form';

const form = new Form('CHAVE_DO_FORMULARIO');

form.on('completed', ev => { console.log(ev); })

form.mount('container-id');
```

Para apontar para um endpoint local:

```javascript
form.endpoint = 'http://localhost:3200';
```

Para desmontar o `iframe` da DOM:

```javascript
form.unmount();
```

## Como contribuir

Instale as dependencias com `pnpm install`.
Expand Down
3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"build:v2": "esbuild packages/v2/index.js --bundle --sourcemap --minify --keep-names --target=safari15 --outfile=build/v2/embedded.js",
"build:v3:sign": "esbuild packages/v3/index.js --bundle --sourcemap --minify --keep-names --target=safari15 --outfile=build/v3/embedded.js",
"build:v3:verify": "esbuild packages/v3/verify.js --bundle --sourcemap --minify --keep-names --target=safari15 --outfile=build/v3/verify.js",
"build:v3": "pnpm run build:v3:sign && pnpm run build:v3:verify"
"build:v3:form": "esbuild packages/v3/form.js --bundle --sourcemap --minify --keep-names --target=safari15 --outfile=build/v3/form.js",
"build:v3": "pnpm run build:v3:sign && pnpm run build:v3:verify && pnpm run build:v3:form"
},
"repository": {
"type": "git",
Expand Down
5 changes: 5 additions & 0 deletions packages/v3/form.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import Form from './src/form/embedded';

globalThis.Form = Form;

export default Form;
11 changes: 11 additions & 0 deletions packages/v3/src/form/embedded.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import BaseEmbed from '../core/base-embed';

export default class Form extends BaseEmbed {
get params() {
return `?embedded=true&origin=${this.origin}`;
}

get path() {
return `/app/click_form/${this.key}`;
}
}
107 changes: 107 additions & 0 deletions packages/v3/src/form/embedded.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import Form from './embedded';

const containerElementId = 'clicksign-embedded-form';
const formKey = 'foobar123';
const endpoint = 'https://app.clicksign.com';

function createContainerElement() {
document.body.innerHTML = '';

const element = document.createElement('div');

element.setAttribute('id', containerElementId);
document.body.appendChild(element);
}

describe('Form', () => {
let instance;

beforeEach(() => {
vi.restoreAllMocks();

createContainerElement();
instance = new Form(formKey);
});

afterEach(() => {
instance.unmount();
});

it('should initialize properly', () => {
const originUrl = window.location.origin;

expect(instance.key).toBe(formKey);
expect(new URL(instance.origin).origin).toBe(originUrl);
expect(instance.endpoint).toBe(endpoint);

const source = new URL(instance.source);
expect(source.origin).toBe(endpoint);
expect(source.pathname).toBe(`/app/click_form/${formKey}`);
expect(source.searchParams.get('embedded')).toBe('true');
expect(new URL(source.searchParams.get('origin')).origin).toBe(originUrl);
});

describe('Mount', () => {
it('should throw when target container does not exist', () => {
expect(() => instance.mount('unknown-container')).toThrow();

instance.iframe = null;
instance.target = null;
});

it('should mount widget on the specified element', () => {
const originUrl = window.location.origin;

instance.mount(containerElementId);

const iframeElement = document.getElementById(containerElementId).children[0];
const iframeSrc = new URL(iframeElement.src);

expect(iframeElement).toBe(instance.iframe);
expect(iframeElement.tagName).toBe('IFRAME');
expect(iframeSrc.origin).toBe(endpoint);
expect(iframeSrc.pathname).toBe(`/app/click_form/${formKey}`);
expect(iframeSrc.searchParams.get('embedded')).toBe('true');
expect(new URL(iframeSrc.searchParams.get('origin')).origin).toBe(originUrl);
});
});

describe('Events', () => {
const events = ['loaded', 'submitted', 'completed', 'error'];

it.each(events)('should register event "%s" listening successfully', (event) => {
const eventMock = vi.fn();
instance.on(event, eventMock);

expect(instance.listen).toHaveProperty(event);
});

it.each(events)('should emit "%s" event with payload', (eventName) => {
const eventMock = vi.fn();
const payload = { name: eventName, metadata: 'sample' };

instance.on(eventName, eventMock);
instance.eventHandler({ data: payload });

expect(eventMock).toHaveBeenCalledWith(payload);
});
});

describe('Unmount', () => {
it('should unmount widget on the specified element', () => {
instance.mount(containerElementId);

const containerElement = document.getElementById(containerElementId);

expect(containerElement.children.length).toEqual(1);
expect(instance.iframe).not.toBeNull();
expect(instance.target).not.toBeNull();

instance.unmount();

expect(containerElement.children.length).toEqual(0);
expect(instance.iframe).toBeNull();
expect(instance.target).toBeNull();
});
});
});
Loading
Loading