From faaf3a61f2944d80b8919c8900325db097944f24 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 10 Oct 2023 14:05:34 +0200 Subject: [PATCH] Add FormEvent stream event test Add sample that shows how FormEvents can be used to create a form submit from a stream of key/value pairs. See gh-30131 --- .../PartEventHttpMessageWriterTests.java | 44 ++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/spring-web/src/test/java/org/springframework/http/codec/multipart/PartEventHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/multipart/PartEventHttpMessageWriterTests.java index 825abaf05f..f02e3890c6 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/multipart/PartEventHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/multipart/PartEventHttpMessageWriterTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2022 the original author or authors. + * Copyright 2002-2023 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,9 @@ package org.springframework.http.codec.multipart; import java.nio.charset.StandardCharsets; import java.time.Duration; +import java.util.AbstractMap; import java.util.Collections; +import java.util.List; import java.util.Map; import org.junit.jupiter.api.Test; @@ -93,6 +95,46 @@ public class PartEventHttpMessageWriterTests extends AbstractLeakCheckingTests { assertThat(decodeToString(part)).isEqualTo("AaBbCc"); } + @Test + void writeFormEventStream() { + Flux> body = Flux.just( + new AbstractMap.SimpleEntry<>("name 1", "value 1"), + new AbstractMap.SimpleEntry<>("name 2", "value 2+1"), + new AbstractMap.SimpleEntry<>("name 2", "value 2+2") + ); + + Flux partEvents = body + .concatMap(entry -> FormPartEvent.create(entry.getKey(), entry.getValue())); + + Map hints = Collections.emptyMap(); + this.writer.write(partEvents, null, MediaType.MULTIPART_FORM_DATA, this.response, hints) + .block(Duration.ofSeconds(5)); + + MultiValueMap requestParts = parse(this.response, hints); + assertThat(requestParts).hasSize(2); + + Part part = requestParts.getFirst("name 1"); + assertThat(part.name()).isEqualTo("name 1"); + assertThat(part.headers().getContentType().isCompatibleWith(MediaType.TEXT_PLAIN)).isTrue(); + String value = decodeToString(part); + assertThat(value).isEqualTo("value 1"); + + List parts = requestParts.get("name 2"); + assertThat(parts).hasSize(2); + + part = parts.get(0); + assertThat(part.name()).isEqualTo("name 2"); + assertThat(part.headers().getContentType().isCompatibleWith(MediaType.TEXT_PLAIN)).isTrue(); + value = decodeToString(part); + assertThat(value).isEqualTo("value 2+1"); + + part = parts.get(1); + assertThat(part.name()).isEqualTo("name 2"); + assertThat(part.headers().getContentType().isCompatibleWith(MediaType.TEXT_PLAIN)).isTrue(); + value = decodeToString(part); + assertThat(value).isEqualTo("value 2+2"); + } + @SuppressWarnings("ConstantConditions") private String decodeToString(Part part) { return StringDecoder.textPlainOnly().decodeToMono(part.content(),