You need to sign in to do that
Don't have an account?
Unit Testing Content
Hi,
I'm trying to write unit tests for Content. It seems that it is impossible to create a Workspace record in Apex, so I guess we have to use an existing one in the org?
Bigger question: If I create a Content record, relate it to an existing workspace using FirstPublishLocationId, and insert it, and then try to make an update to that Content record, I get this error:
Document with ID: 06930000000YPbp already has an owning Workspace
I get the same error whether or not this is in a test class. If I do it outside of a test class, and just use the record Id a few seconds later to do my update, it will work. So, it seems to be time-based... Is it not possible to update a newly created Content record from within a test class?
Thanks,
Tom
I'm getting the same error. I'm attempting to run a test method on a Content record update that contains a ContentURL - essentially trying to update the Content URL.
I have inserted two different ContentVersion records, one using a FIle and PAthOnclient, the other using a COntentURL. Both records insert correctly, and the FIle CV is able to refresh its content in APEX by inserting a new CV record using the COntentDOcument ID.
However, attempting to update the COntentURL on that CV is causing the same error - from the debug log:
02:05:50.859|DML_BEGIN|[254]|Op:Update|Type:ContentVersion|Rows:1
02:05:50.898|DML_END|[254]
02:05:50.898|EXCEPTION_THROWN|[254]|System.DmlException: Update failed. First exception on row 0 with id 068S00000009CyZIAU; first error: FIELD_INTEGRITY_EXCEPTION, Document with ID: 069S00000000p2v already has an owning Workspace: []
Now I know the Document has an owning workspace, and whereas I did publish the document to a workspace on insert for both CV records, only the COntentURL CV is complaining about already having an owning Workspace, as if I'm trying to move it to a new Workspace - which I am not. Both records are following the same update procedure.
ALSO, I physically added a third ContentURL CV and queried this record into the test method, and it updated with no problem, so it doesn't appear to be assiciated with COntentURL-type CVs (and no, I'm not using ContentTypes at all)
I realize that Content isn't really much of a big deal to the Salesforce folks these days, what with Chatter, Database,com, VMWare all ramping up- Content seems like a bit of an afterthought - no one I spoke to at Dreamforce knew anything about Content or any roadmap as to its improvement. But this is a weird glitch, and the error message isn't telling me enough to figure out how to resolve it so it would be really cool if someone could provide some guidance to what could be happening here given that nothing in the code is attempting to update or add a new ContentWorkspaceDoc record, or delete the old one and change it, or anything else having to do with the workspaces.
Just want to update the ContentURL and maybe a couple of custom fields. That's it!
Thanks
Have either of you guys found a solution to this?
I want to move owning workspaces using code and I'm getting this error. I can change nonowning workspaces using code just fine.
I think there's just not a lot of people trying to do anything with Content in APEX and that's why no responses.
Unfortunately, I never found a solution. We had to pick a random existing Content record in the org (that met a few criterai) for the unit tests. It's a horrible test, but I can't figure any way around it.
I have found a solution!!
Here's the deal: Any content record inserted in a test method using the standard API insertion process will throw this error when you try to update that same test record. It has to do with the FirstPublishLocationID being set during the insert somehow not being released in memory for some reason such that when you update that same record, the system thinks you're still trying to assign that value.
The only way around this is to insert a test record you plan to update using a process that mimics the UI insertion. Here;s how you do that:
First insert the Test Content record with just the VersionData/PathOnClient combination or a ContentURL, the Title, and if appropriate, the Record TypeID (as this can't be set with an update).
Once that is inserted, query the ContentDocumentId for that new record, as well as the id of the ContentWorkspace you want to initially publish it to, Using those ids, create a ContentWorkspaceDoc record (as opposed to using the FirstPublishLocationId). Then query your new Test Content record for any custom fields, add values for those fields and update the Test Content record.
At that point, you have the same Content Record you would have had had you used the standard API insertion, except you never actually had to assign the FirstPublishLocationId, which is the source of the error.
At that point you should be able to use that recordfor any subsequent update tests.
In my case, I have a web service adding content provided by outside systems. I am using the standard API insert method in that web service due to a really bad Salesforce bug that occurs if you use the UI-mimic method in practice - the Storage Usage limits are increased 3-FOLD!!!! That;s both the number of bytes and the number of records - EVEN THOUGH ONLY ONE ACTUAL RECORD IS INSERTED. Deleting the record is successful, but only updates the Storage Usage numbers by the value of that one record.
In other words: Using an APEX process to mimic the UI insertion as described above on a 1 Mb file will cause the Storage USage to thisnk you have just loaded 3 files adding up to 3Mb in your storage Usage capacity. Deleting that file only removes the 1 file and 1Mb, leaving the 2 files and 2Mb counting against your Storage capacity, even though there are no files. This has been confirmed several times by a Tier 3 Support rep.
However, in a test method the Storage Usage limits aren't impacted so you can use the UI-mimiv method to add Test Files to a test method, and thus allow for the ability to update in the Test method.
Good luck getting your tests to work.
Thanks for the responses to this. It has helped immensely, but it's shown some glaring shortcomings in Salesforce Content that Salesforce themselves have refused to include in documentation.
I've got one last question on this. I'm using different content workspaces to enforce permissions on content. When I load content, I don't have the luxury of not putting a FirstPublishLocationId because if I don't, I can't add in values in the custom fields on the Content record or add tags to it.
I can share content with workspaces in code by adding rows to ContentWorkspaceDoc and I can unshare by deleting rows from ContentWorkspaceDoc. But I can only do this where IsOwner = false .
But for permissions to work properly, I need to move the workspace, or in database parlance, I need to change the WorkspaceId for the record where IsOwner = true. I get the FIELD_INTEGRITY_EXCEPTION, Document already has an owning Workspace error.
I try inserting a record, I get the error. As you'd expect. I try updating the record that's already there to change the WorkspaceId. I still get the error. So if it doesn't allow inserts and it doesn't allow updates, just how do you change the Owning Workspace in APEX code?
I'm in deep trouble with this with a client's project and I may have to tell them that Salesforce.com has really let them down.
hello OldDeadBug could you plz elobrate your post... About how to insert a content object and set the custom fileds with values so that i could make my test class based on content object to have much more coverage...
Hey Pradeep@cloud,
If you're working with custom fields on a Content record, you'll have to associate it to a Workspace, and you'll get the same error whether or not this is in a test class. If you do this outside of a test class, and just use the record Id a few seconds later to do my update, it will work. So, it seems to be time-based... FirstPublishLocationId seems to kick off an asynchronous process to create the ContentDocument and ContentWorkspaceDoc records from your ContentVersion record.
The solution seems to be to insert a ContentVersion record, select an Id from your chosen Workspace, and select the ContentDocumentId from your newly created ContentVersion. You can then create your own ContentWorkspaceDoc record to relate the ContentDocument to the ContentWorkspace, and update your custom field on the ContentVersion record.
public ID setupContent()
{
RecordType ContentRT = [select Id FROM RecordType WHERE Name = 'Category'];
ContentVersion testContentInsert = new ContentVersion();
testContentInsert.ContentURL='http://www.google.com/';
testContentInsert.Title = 'Google.com';
testContentInsert.RecordTypeId = ContentRT.Id;
insert testContentInsert;
ContentVersion testContent = [SELECT ContentDocumentId FROM ContentVersion where Id = :testContentInsert.Id];
ContentWorkspace testWorkspace = [SELECT Id FROM ContentWorkspace WHERE Name = 'My Library'];
ContentWorkspaceDoc newWorkspaceDoc = new ContentWorkspaceDoc();
newWorkspaceDoc.ContentWorkspaceId = testWorkspace.Id;
newWorkspaceDoc.ContentDocumentId = testContent.ContentDocumentId;
insert newWorkspaceDoc;
testContent.iPad_Content_Views__c = 0;
update testContent;
return testContentInsert.Id;
}
Thanks a lot Echo, Your post really helped me solve my issues, Thanks a lot :)...... I have been sitting on this from past few days and had lost all the interest anyhow thanks for your help i was able to solve it....
Happy to help!