Skip to content

Commit

Permalink
Add condecov with scratch org (#7)
Browse files Browse the repository at this point in the history
* Add Codecov integration for apex (#6)

* Add Codecov integration for apex

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* --amend

* Add condecov with scratch org
  • Loading branch information
nicolasparrague authored Jun 7, 2024
1 parent 4b90f6c commit a4cb41e
Show file tree
Hide file tree
Showing 7 changed files with 326 additions and 5 deletions.
17 changes: 13 additions & 4 deletions .github/workflows/code-coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,24 @@ jobs:
run: 'sfdx force:auth:sfdxurl:store -f ./SALESFORCE_AUTH_URL.txt -a devhub -d'

- name: Authenticate Target Org
run: 'sfdx force:auth:sfdxurl:store -f ./SALESFORCE_AUTH_URL.txt -a targetOrg'

run: 'sfdx force:auth:sfdxurl:store -f ./SALESFORCE_AUTH_URL.txt -a ciorg'

- name: Create Scratch Org
run: sfdx org create scratch -f config/project-scratch-def.json -a ciorg --set-default

- name: Deploy source
run: sfdx project deploy start -o targetOrg
run: sfdx project deploy start

- name: Run Apex tests
run: sfdx apex run test -o targetOrg --codecoverage --resultformat human -d ./
run: sfdx apex run test -o ciorg --codecoverage --resultformat human -d ./

- name: Upload code coverage for Apex to Codecov.io
uses: codecov/codecov-action@v2
with:
flags: Apex
flags: Apex

- name: Delete Scratch Org
if: always()
run: |
sfdx org delete scratch -o ciorg -p
1 change: 0 additions & 1 deletion config/project-scratch-def.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
"orgName": "Demo company",
"edition": "Developer",
"features": ["EnableSetPasswordInApi"],
"lockerServiceNext" : false,
"settings": {
"lightningExperienceSettings": {
"enableS1DesktopEnabled": true
Expand Down
221 changes: 221 additions & 0 deletions src-lookup/main/default/lwc/ldsUtils/__tests__/ldsUtils.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
import { reduceErrors } from "c/ldsUtils";

describe("c-lds-utils", () => {
describe("reduceErrors", () => {
it("reduces single error with message in body", () => {
const FULL_ERROR = { body: { message: "mockError" } };
const REDUCED_ERROR = [FULL_ERROR.body.message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single error with multiple bodies with messages", () => {
const FULL_ERROR = {
body: [{ message: "mockError1" }, { message: "mockError2" }]
};
const REDUCED_ERROR = [
FULL_ERROR.body[0].message,
FULL_ERROR.body[1].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single error message string", () => {
const FULL_ERROR = { message: "mockError" };
const REDUCED_ERROR = [FULL_ERROR.message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces array of error message string", () => {
const FULL_ERROR = [{ message: "mockError1" }, { message: "mockError2" }];
const REDUCED_ERROR = [FULL_ERROR[0].message, FULL_ERROR[1].message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single UI API fieldError with error message string", () => {
const FULL_ERROR = [
{
body: {
output: {
fieldErrors: { field1: [{ message: "mockError1" }] }
}
}
}
];
const REDUCED_ERROR = [
FULL_ERROR[0].body.output.fieldErrors.field1[0].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces array of UI API fieldErrors with error message string", () => {
const FULL_ERROR = [
{
body: {
output: {
fieldErrors: {
field1: [{ message: "mockError1" }],
field2: [{ message: "mockError2" }]
}
}
}
}
];
const REDUCED_ERROR = [
FULL_ERROR[0].body.output.fieldErrors.field1[0].message,
FULL_ERROR[0].body.output.fieldErrors.field2[0].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces UI API single page level error with error message string", () => {
const FULL_ERROR = {
body: {
output: {
errors: [
{
message: "mockError"
}
]
}
}
};

const REDUCED_ERROR = [FULL_ERROR.body.output.errors[0].message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces UI API multiple page level error with error message string", () => {
const FULL_ERROR = {
body: {
output: {
errors: [
{
message: "mockError1"
},
{
message: "mockError2"
}
]
}
}
};

const REDUCED_ERROR = [
FULL_ERROR.body.output.errors[0].message,
FULL_ERROR.body.output.errors[1].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single page level error with error message string", () => {
const FULL_ERROR = {
body: {
pageErrors: [
{
message: "mockError"
}
]
}
};

const REDUCED_ERROR = [FULL_ERROR.body.pageErrors[0].message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces multiple page level error with error message string", () => {
const FULL_ERROR = {
body: {
pageErrors: [
{
message: "mockError1"
},
{
message: "mockError2"
}
]
}
};

const REDUCED_ERROR = [
FULL_ERROR.body.pageErrors[0].message,
FULL_ERROR.body.pageErrors[1].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single fieldError with error message string", () => {
const FULL_ERROR = [
{
body: {
fieldErrors: { field1: [{ message: "mockError1" }] }
}
}
];
const REDUCED_ERROR = [FULL_ERROR[0].body.fieldErrors.field1[0].message];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces array of fieldErrors with error message string", () => {
const FULL_ERROR = [
{
body: {
fieldErrors: {
field1: [{ message: "mockError1" }],
field2: [{ message: "mockError2" }]
}
}
}
];
const REDUCED_ERROR = [
FULL_ERROR[0].body.fieldErrors.field1[0].message,
FULL_ERROR[0].body.fieldErrors.field2[0].message
];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});

it("reduces single error with unknown shape", () => {
const FULL_ERROR = { statusText: "mockStatus" };
const REDUCED_ERROR = [FULL_ERROR.statusText];

const reduced = reduceErrors(FULL_ERROR);

expect(reduced).toStrictEqual(REDUCED_ERROR);
});
});
});
70 changes: 70 additions & 0 deletions src-lookup/main/default/lwc/ldsUtils/ldsUtils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* Reduces one or more LDS errors into a string[] of error messages.
* @param {FetchResponse|FetchResponse[]} errors
* @return {String[]} Error messages
*/
export function reduceErrors(errors) {
if (!Array.isArray(errors)) {
errors = [errors];
}

return (
errors
// Remove null/undefined items
.filter((error) => !!error)
// Extract an error message
.map((error) => {
// UI API read errors
if (Array.isArray(error.body)) {
return error.body.map((e) => e.message);
}
// Page level errors
else if (error?.body?.pageErrors && error.body.pageErrors.length > 0) {
return error.body.pageErrors.map((e) => e.message);
}
// Field level errors
else if (
error?.body?.fieldErrors &&
Object.keys(error.body.fieldErrors).length > 0
) {
const fieldErrors = [];
Object.values(error.body.fieldErrors).forEach((errorArray) => {
fieldErrors.push(...errorArray.map((e) => e.message));
});
return fieldErrors;
}
// UI API DML page level errors
else if (
error?.body?.output?.errors &&
error.body.output.errors.length > 0
) {
return error.body.output.errors.map((e) => e.message);
}
// UI API DML field level errors
else if (
error?.body?.output?.fieldErrors &&
Object.keys(error.body.output.fieldErrors).length > 0
) {
const fieldErrors = [];
Object.values(error.body.output.fieldErrors).forEach((errorArray) => {
fieldErrors.push(...errorArray.map((e) => e.message));
});
return fieldErrors;
}
// UI API DML, Apex and network errors
else if (error.body && typeof error.body.message === "string") {
return error.body.message;
}
// JS errors
else if (typeof error.message === "string") {
return error.message;
}
// Unknown error shape so try HTTP status text
return error.statusText;
})
// Flatten
.reduce((prev, curr) => prev.concat(curr), [])
// Remove empty strings
.filter((message) => !!message)
);
}
5 changes: 5 additions & 0 deletions src-lookup/main/default/lwc/ldsUtils/ldsUtils.js-meta.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="UTF-8" ?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>56.0</apiVersion>
<isExposed>false</isExposed>
</LightningComponentBundle>
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomObject xmlns="http://soap.sforce.com/2006/04/metadata">
<label>Lookup</label>
<pluralLabel>Lookups</pluralLabel>
<visibility>Public</visibility>
</CustomObject>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<CustomField xmlns="http://soap.sforce.com/2006/04/metadata">
<fullName>Interface__c</fullName>
<externalId>false</externalId>
<fieldManageability>DeveloperControlled</fieldManageability>
<label>Interface</label>
<length>255</length>
<required>true</required>
<type>Text</type>
<unique>false</unique>
</CustomField>

0 comments on commit a4cb41e

Please sign in to comment.