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

Hutte Apex Frameworks Collection #2

Merged
merged 11 commits into from
Jan 18, 2024
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
5 changes: 4 additions & 1 deletion .forceignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,7 @@ package.xml
**/.eslintrc.json

# LWC Jest
**/__tests__/**
**/__tests__/**

# Frameworks
frameworks/**
21 changes: 21 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2024 Hutte

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,10 @@ Created with ```sf project generate```, with
- ESLint baseline configuration
- Precommit Husky hook configured with prettier formating

Please check https://docs.hutte.io in order to learn more about setting up and using Hutte.
## Frameworks

Hutte Apex Collection is a set of useful open source Apex frameworks for Salesforce development, built by contributors in the Salesforce community, [see more](./frameworks/README.md).

------------------------

Please check https://docs.hutte.io in order to learn more about setting up and using Hutte.
27 changes: 20 additions & 7 deletions config/project-scratch-def.json
Original file line number Diff line number Diff line change
@@ -1,14 +1,27 @@
{
"orgName": "Hutte Recipes",
"edition": "Developer",
"edition": "Enterprise",
"hasSampleData": true,
"country": "US",
"language": "en_US",
"features": ["EnableSetPasswordInApi"],
"features": [],
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
"chatterSettings": {
"enableChatter": false
},
"mobileSettings": {
"enableS1EncryptedStoragePref2": false
"communitiesSettings": {
"enableNetworksEnabled": false
},
"pathAssistantSettings": {
"pathAssistantEnabled": false
},
"securitySettings": {
"enableAdminLoginAsAnyUser": false
},
"userManagementSettings": {
"enableEnhancedPermsetMgmt": true,
"enableEnhancedProfileMgmt": true,
"enableNewProfileUI": true
}
}
}
}
37 changes: 37 additions & 0 deletions frameworks/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Hutte Apex Collection

## What does it include?

Hutte Apex Collection is a set of useful open source Apex frameworks for Salesforce development, built by contributors in the Salesforce community

These are:

- [Apex Trigger Actions](https://github.com/mitchspano/apex-trigger-actions-framework)
- [Amoss - Apex Mocks](https://github.com/bobalicious/amoss)
- [Nebula Logger](https://github.com/jongpie/NebulaLogger)
- [SOQL-Lib](https://github.com/beyond-the-cloud-dev/soql-lib)
- [Apex Domain Builder](https://github.com/rsoesemann/apex-domainbuilder)
- [Apex Http Mocks](https://github.com/rsoesemann/apex-httpmock)

## Why to create a Collection?

While these can be deployed (or even installed as an unlocked package) independently, Hutte provides these bundled in an Unlocked Package to set a project baseline in a single-installation. Besides, this Hutte collection can be extended with new open source frameworks (either by Hutte or external contribution) and new versions of this unlocked package can be created.

## Unlocked Package

### Links

- [Installation link for Production](https://login.salesforce.com/packaging/installPackage.apexp?p0=04tS70000000IxpIAE)
- [Installation link for Sandbox](https://test.salesforce.com/packaging/installPackage.apexp?p0=04tS70000000IxpIAE)

<img src="./docs/images/unlocked-package-installation.png" alt="drawing" width="500"/>

## Considerations

As a baseline, these frameworks cover the basics of a Salesforce implementation, for example, a Apex triggers management using [Apex Trigger Actions](https://github.com/mitchspano/apex-trigger-actions-framework), a logging system with [Nebula Logger](https://github.com/jongpie/NebulaLogger) or a SOQL light-weight library with [SOQL-Lib](https://github.com/beyond-the-cloud-dev/soql-lib), among others.
This collection is not currently including many other valuable frameworks existing in the open source community to keep it simple in initial versions.
Besides, while creating this collection, it's prioritized to use frameworks that use the newest features of apex development, such as [user mode](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_enforce_usermode.htm), and are as simple and complete as possible.

## Contributions

External contributions are welcomed, either through Pull Request, Github Issues or any other feasible alternative.
21 changes: 21 additions & 0 deletions frameworks/apex-domainbuilder/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2019 Robert Sösemann

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
77 changes: 77 additions & 0 deletions frameworks/apex-domainbuilder/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
# Apex Domain Builder [![Codacy Badge](https://api.codacy.com/project/badge/Grade/3814b20244d14e3d846ff05dfd3c2e2a)](https://www.codacy.com/app/rsoesemann/apex-domainbuilder?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=rsoesemann/apex-unified-logging&amp;utm_campaign=Badge_Grade)

From https://github.com/rsoesemann/apex-domainbuilder

Test Data Builder framework to setup test data for complex Apex integration tests in a concise, readable and flexible way.

<a href="https://githubsfdeploy.herokuapp.com?owner=rsoesemann&repo=apex-domainbuilder">
<img alt="Deploy to Salesforce"
src="https://raw.githubusercontent.com/afawcett/githubsfdeploy/master/src/main/webapp/resources/img/deploy.png">
</a>

Setting up test data for complex Apex integration tests is not easy, because you need to..:

- set required fields even if irrelevant for the test
- insert the objects in the right order
- create relationships by setting Lookup fields
- put ugly `__c` all over the place
- clutter your code with `Map<Id, SObject>` to keep track of related records
- reduce the DML statements to not hit Governor Limits

TestFactories as used by many developers and recommended by Salesforce.com can help to minimize ugly setup code by moving it to seperate classes. But over the time those classes tend to accumulate complexity and redundant spaghetti code.

In the world of Enterprise software outside of Salesforce.com there are experts that have created patterns for flexible and readable (fluent, concise) test data generation. Among them the most notable is Nat Pryce who wrote a great book about testing and somewhat invented the [Test Data Builder](http://www.natpryce.com/articles/000714.html) pattern.

**apex-domainbuilder** brings those ideas to Apex testing:
1. By incorporating a simple small Builder class for each test-relevant Domain SObject we centralize all the creation knowledge and eliminating redundancy.

```java
@IsTest
public class Account_t extends DomainBuilder {

public Account_t() {
super(Account.SObjectType);

name('Acme Corp');
}

public Account_t name(String value) {
return (Account_t) set(Account.Name, value);
}

public Account_t add(Opportunity_t opp) {
return (Account_t) opp.setParent(Opportunity.AccountId, this);
}

public Account_t add(Contact_t con) {
return (Account_t) con.setParent(Contact.AccountId, this);
}
}
```
2. By internally leveraging the [`fflib_SObjectUnitOfWork`](https://github.com/financialforcedev/fflib-apex-common/blob/master/fflib/src/classes/fflib_SObjectUnitOfWork.cls) for the DML all test run dramatically faster.
3. The [Fluent Interface](https://en.wikipedia.org/wiki/Fluent_interface) style of the Builder pattern combined with having all the database wiring encapsulated in the Unit of work made each test much more understandable.
```java
@IsTest
private static void easyTestDataCreation() {

// Setup
Contact_t jack = new Contact_t().first('Jack').last('Harris');

new Account_t()
.name('Acme Corp')
.add( new Opportunity_t()
.amount(1000)
.closes(2019, 12)
.contact(jack))
.persist();

// Exercise
...


// Verify
...
}
```
4. Using Graph algorithms to autodetect the correct insert order in the Unit Of Work.
5. Is able to handle self-reference fields (e.g. Manager Contact Lookup on Contact) by using a patched fflib Unit of Work.
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
@IsTest
public class Account_t extends DomainBuilder {

public Account_t() {
super(Account.SObjectType);

name('Acme Corp');
}

public Account_t name(String value) {
return (Account_t) set(Account.Name, value);
}


public Account_t add(Opportunity_t o) {
return (Account_t) o.setParent(Opportunity.AccountId, this);
}

public Account_t add(Contact_t c) {
return (Account_t) c.setParent(Contact.AccountId, this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>54.0</apiVersion>
<status>Active</status>
</ApexClass>
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
public class Contact_t extends DomainBuilder {

public Contact_t(Account_t a) {
super(Contact.SObjectType);
setParent(Contact.AccountId, a);

last(new Random().string());
}

public Contact_t() {
this(new Account_t());
}

public Contact_t first(String value) {
return (Contact_t) set(Contact.FirstName, value);
}

public Contact_t last(String value) {
return (Contact_t) set(Contact.LastName, value);
}

public Contact_t email(String value) {
return (Contact_t) set(Contact.Email, value);
}

public Contact_t reports(Contact_t c) {
return (Contact_t) setParent(Contact.ReportsToId, c);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8"?>
<ApexClass xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>54.0</apiVersion>
<status>Active</status>
</ApexClass>
Loading