Skip to content

Commit

Permalink
Merge pull request apex-enterprise-patterns#4 from OrtooApps/feature/…
Browse files Browse the repository at this point in the history
…add-initial-base-lwcs

Feature/add initial base lwcs
  • Loading branch information
rob-baillie-ortoo committed Dec 16, 2021
2 parents 78dabd3 + d662d81 commit 6343a26
Show file tree
Hide file tree
Showing 37 changed files with 22,380 additions and 9 deletions.
14 changes: 12 additions & 2 deletions .github/workflows/create-org-and-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,21 @@ jobs:
- name: Deploy framework to Org
run: sfdx force:source:deploy -p framework --targetusername "${{env.ORG_ALIAS_PREFIX}}${{github.run_number}}"

# Run All Unit Tests
# Run Apex Unit Tests

- name: Run All Unit Tests
- name: Run Apex Unit Tests
run: sfdx force:apex:test:run -r human -u "${{env.ORG_ALIAS_PREFIX}}${{github.run_number}}" --codecoverage --wait 20 | grep -v ' Pass '; test ${PIPESTATUS[0]} -eq 0

# Prepare Jest Modules

- name: Prepare Jest Modules
run: npm install

# Run Jest Unit Tests

- name: Run Jest Unit Tests
run: npm test

# Delete Scratch Org

- name: Delete Scratch Org
Expand Down
2 changes: 0 additions & 2 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run precommit
37 changes: 36 additions & 1 deletion TODO.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,45 @@ Licenses that are needed with the source code and binary:
* SObject Fabricator - https://github.com/bobalicious/SObjectFabricator/blob/master/LICENSE

Look at the use of 'MockDatabase' in fflib

Look at:
SobjectUtils.getSobjectName

* LWCs
* Write up:
* Layout Constants
* View and Edit Form

* Standards for:
* Edit Forms / Validation
* Edit Forms with Child Records

* Review:
* Self Configured Combobox - not sure it's needed

* Try parent and datatable referencing a DML Service


* Can the view and edit form call the validate method?

* Standards
* data-name to identify elements in a test
* e.g. [data-name="cancel"]
* Labels should be:
* Imported into a static named _LABEL
* Referenced in an object named 'labels'.
* E.g.
labels = {
confirm: CONFIRM_LABEL
}
* so in the html it's {labels.confirm}
* Do not add a target unless you KNOW it is appropriate.
* Once you add it, it cannot be removed
* Always qualify the record page target with the sobject types it's appropriate for

* use standard validation techniques
* Add the property data-validatable
* call reportValidity, binding it to the LWC

* To finalise the core architecture:
* Do we need to have a non all-or-nothing version of commitWork?

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,60 @@
<shortDescription>Message when CRUD violation occurs on a publish. {0} is the name of the Event.</shortDescription>
<value>Attempted to publish {0} events without the required permission</value>
</labels>
<labels>
<fullName>ortoo_core_close</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Close', capitalised.</shortDescription>
<value>Close</value>
</labels>
<labels>
<fullName>ortoo_core_cancel</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Cancel', capitalised.</shortDescription>
<value>Cancel</value>
</labels>
<labels>
<fullName>ortoo_core_confirm</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Confirm', capitalised.</shortDescription>
<value>Confirm</value>
</labels>
<labels>
<fullName>ortoo_core_yes</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Yes', capitalised.</shortDescription>
<value>Yes</value>
</labels>
<labels>
<fullName>ortoo_core_no</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'No', capitalised.</shortDescription>
<value>No</value>
</labels>
<labels>
<fullName>ortoo_core_save</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Save', capitalised.</shortDescription>
<value>Save</value>
</labels>
<labels>
<fullName>ortoo_core_edit</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The word 'Edit', capitalised.</shortDescription>
<value>Edit</value>
</labels>
<labels>
<fullName>ortoo_core_error_title</fullName>
<language>en_US</language>
<protected>false</protected>
<shortDescription>The title that is used on generic errors in standard Ortoo LWCs.</shortDescription>
<value>Error</value>
</labels>
</CustomLabels>
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
import { createElement } from 'lwc';
import ConfirmationDialog from 'c/confirmationDialog';

describe('c-confirmation-dialog', () => {
afterEach(() => {
// The jsdom instance is shared across test cases in a single file so reset the DOM
while (document.body.firstChild) {
document.body.removeChild(document.body.firstChild);
}
});

it('When set to visible, with a title, contains a div with the title, directing it to the title slot of the modal', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
element.visible = true;
element.title = 'A title';
document.body.appendChild(element);

return Promise.resolve()
.then( () => {
const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="title"]' );
expect( expectedElement ).not.toBe( null );
});
});

it('When set to visible, contains a div containing a message slot, directing it to the contents slot of the modal', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
element.visible = true;
document.body.appendChild(element);

const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="contents"]' );
expect( expectedElement ).not.toBe( null );
});

it('When set to visible and no button labels provided contains a div containing cancel and confirm buttons with the defaulted labels, directing them to the modal footer slot', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
element.visible = true;
document.body.appendChild(element);

const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );

expect( expectedElement.querySelector( '[data-name="confirm"]' ).title ).not.toBe( null );
expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).not.toBe( null );
expect( expectedElement.querySelector( '[data-name="cancel"]' ).title ).not.toBe( null );
expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).not.toBe( null );
});

it('When set to visible, contains a div containing cancel and confirm buttons with the specified labels, directing them to the modal footer slot', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
element.type = 'save';
element.confirmLabel = 'Confirm thing';
element.cancelLabel = 'Cancel thing';
element.visible = true;
document.body.appendChild(element);

const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );

expect( expectedElement.querySelector( '[data-name="confirm"]' ).title ).toBe( 'Confirm thing' );
expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).toBe( 'Confirm thing' );
expect( expectedElement.querySelector( '[data-name="cancel"]' ).title ).toBe( 'Cancel thing' );
expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).toBe( 'Cancel thing' );
});

it('When set to visible and passed a valid type, contains a div containing cancel and confirm buttons with the specified labels, directing them to the modal footer slot', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
element.type = 'save';
element.visible = true;
document.body.appendChild(element);

const expectedElement = element.shadowRoot.querySelector( 'c-modal div[slot="footer"]' );
expect( expectedElement ).not.toBe( null );

expect( expectedElement.querySelector( '[data-name="confirm"]' ).label ).not.toBe( null );
expect( expectedElement.querySelector( '[data-name="cancel"]' ).label ).not.toBe( null );
});

it('When set to an invalid type, will throw an error', () => {
const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});
expect( () => element.type = 'invalid' ).toThrowError( 'Invalid type specified, should be one of confirm, yesNo, save' );
});

it('Clicking the confirm button will issue an event containing the confirm event message', () => {

const CONFIRM_MESSAGE = 'The confirm message';
const CANCEL_MESSAGE = 'The cancel message';

const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});

element.confirmEventMessage = CONFIRM_MESSAGE;
element.cancelEventMessage = CANCEL_MESSAGE;

element.visible = true;
document.body.appendChild(element);

const confirmHandler = jest.fn();
element.addEventListener( 'confirm', confirmHandler ) ;

const cancelHandler = jest.fn();
element.addEventListener( 'cancel', cancelHandler ) ;

element.shadowRoot.querySelector( '[data-name="confirm"]' ).click();

expect( confirmHandler ).toHaveBeenCalled();
expect( confirmHandler.mock.calls[0][0].detail ).toBe( CONFIRM_MESSAGE );

expect( cancelHandler ).not.toHaveBeenCalled();
});

it('Clicking the cancel button will issue an event containing the cancel event message', () => {

const CONFIRM_MESSAGE = 'The confirm message';
const CANCEL_MESSAGE = 'The cancel message';

const element = createElement('c-confirmation-dialog', {
is: ConfirmationDialog
});

element.confirmEventMessage = CONFIRM_MESSAGE;
element.cancelEventMessage = CANCEL_MESSAGE;

element.visible = true;
document.body.appendChild(element);

const confirmHandler = jest.fn();
element.addEventListener( 'confirm', confirmHandler ) ;

const cancelHandler = jest.fn();
element.addEventListener( 'cancel', cancelHandler ) ;

element.shadowRoot.querySelector( '[data-name="cancel"]' ).click();

expect( cancelHandler ).toHaveBeenCalled();
expect( cancelHandler.mock.calls[0][0].detail ).toBe( CANCEL_MESSAGE );

expect( confirmHandler ).not.toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
<template>
<c-modal
visible={visible}
oncancel={handleCancel}
>

<div slot="title">
<slot name="title"></slot>
</div>

<div slot="contents">
<slot name="message"></slot>
</div>

<div slot="footer">
<lightning-button-group>
<lightning-button
variant="neutral"
name="cancel"
data-name="cancel"
label={cancelLabel}
title={cancelLabel}
onclick={handleCancel}
></lightning-button>
<lightning-button
variant="brand"
name="confirm"
data-name="confirm"
label={confirmLabel}
title={confirmLabel}
onclick={handleConfirm}
></lightning-button>
</lightning-button-group>
</div>
</c-modal>
</template>
Loading

0 comments on commit 6343a26

Please sign in to comment.