testingisdocumenting/webtau

Unable to create MultiPartFormField with specific content-types for files

Opened this issue · 2 comments

The current dsl helper methods do not allow setting a content type via fileFormField()methods, and default to application/octet-stream. Also the constructor for MultiPartFormField is private. We have scenarios where we need to set the content type for specific MultiPart fields (such as text/csv or text/tab-separated-values).

I was able to work around this using reflection to access the private constructor.

// access private ctor since we need to set file content type
var fileBytes = Files.readAllBytes(Path.of(fileName));
Constructor<MultiPartFormField> multiPartFormFieldConstructor = MultiPartFormField.class.getDeclaredConstructor(String.class, String.class, byte[].class, String.class);
multiPartFormFieldConstructor.setAccessible(true);
MultiPartFormField multiPartFormField = multiPartFormFieldConstructor.newInstance("file", "text/tab-separated-values", fileBytes, fileName);
var formData = http.formData(multiPartFormField);

There are several solutions I can think of to deal with this.

  1. Add new fileFormField helper methods with String contentType argument.
  2. Make the constructor public. It might be difficult to handle all of the different combinations of possible arguments. If the constructor was public you could always fall back on that.
  3. If you don't want a public constructor, then add a single helper method that takes all 4 of the MultiPartFormField values.
  4. Make the constructor protected. I could have created class that extends MultiPartFormField which would have been cleaner than using reflection to change access level of the constructor

The easiest solution might be to just make the constructor public, but the cleanest might be to add new methods to the dsl. One issue is there are already numerous methods that accept multiple String arguments, but the following two methods would allow for a fairly simple fileFormField as well as binaryFormField that would also satisfy option 3 above.

public static  MultiPartFormField binaryFormField(String fieldName, String contentType, byte[] content, String fileName) {
    return new MultiPartFormField(fieldName, contentType, content, fileName);
}
public static  MultiPartFormField fileFormField(String fieldName, Path file, String fileName, String contentType) {
    return binaryFormField(fieldName, contentType, FileUtils.fileBinaryContent(file), fileName);
}

Hello @efrench-novi,
thank you for reporting and finding work around!

Wanted to ask if you by any chance interested in creating a PR?
Let me know and we can talk details.

@efrench-novi ping just in case you missed it