I think you're confusing object-level and record-level permissions. Profiles and permission sets determine how a user can interact with an object, such as Leads, Accounts, and Opportunities. Unless you set View All/Modify All for an object that user may or may not have access to individual records.
Sharing rules modify which records a user can see and edit, providing the user's profile allows for such actions. I can share Opportunities with a user, but if that user's profile does not provide at least Read access to Opportunities that user will never see those records.
Update
UserRecordAccess tells you what access the user has to a particular record; this is the culmination of all of the security settings, starting with the user's profile and assigned permission sets and then applying your global security settings and sharing rules.
If a user is not assigned a profile or permission set granting Edit to the object then UserRecordAccess will always be false since the user does not have access to edit that object.
To the specific compiling problem from the question rather than the larger problems with how the test is running.
Engagement__c testE = [SELECT Id FROM Engagement__c WHERE Status__c = 'New' LIMIT 1];
if(testE.size() > 0)
testE = testE[0].Id;
In the first line of this snippet testE
is declared as a variable of type Engagement__c
.
Then in the last line of the snippet the code tries to access the first element of the collection and assign the Id field from that back to the testE
variable.
The problem with this is that testE
isn't a List or Set that represents a collection. I.e. It is just a single Engagement__c
instance rather than List<Engagement__c>
. The other problem is that you can't assign an Id to a Engagement__c type.
Something like the following would make more sense:
List<Engagement__c> newEngagements = [SELECT Id FROM Engagement__c WHERE Status__c = 'New' LIMIT 1];
if(newEngagements.size() > 0) {
Id idOfNewEngagement = newEngagements[0].Id;
// ...
} else {
System.assert(false, 'Expected at least one Engagement for valid test execution');
}
However, as both Adrian and Rao have commented, the general idea of querying for an existing Engagement__c record using @SeeAllData=true is a really bad.
What happens to your test if that record doesn't exist in production currently? As you found out with the original code, you get a List has no rows for assignment to SObject
error is you assume the SOQL query will return at least one record.
It might be there one day and then gone the next. Much better to script in all the data that your test depends on so it will work consistently regardless of the current state of the data in the org.
See also:
Best Answer
You can use insert to share opportunity share. Also if you want to update any share records you will need to first delete the existing share records for the user and insert the new one. Hope this helps.