mirror of https://github.com/halo-dev/halo
Provide ungrouped query param to filter ungrouped attachments (#2752)
#### What type of PR is this? /kind feature /area core /milestone 2.0.0-rc.1 #### What this PR does / why we need it: Provide `ungrouped` query param to filter ungrouped attachments. Please note that we will ignore `group` query param when `ungropued` is `true`. ```bash curl -X 'GET' \ 'http://localhost:8090/apis/api.console.halo.run/v1alpha1/attachments?ungrouped=true' \ -H 'accept: */*' ``` #### Which issue(s) this PR fixes: Fixes https://github.com/halo-dev/halo/issues/2451 #### Does this PR introduce a user-facing change? ```release-note None ```pull/2760/head
parent
b0c461b5f6
commit
f96ef7f1b3
|
@ -4,6 +4,7 @@ import static java.util.Comparator.comparing;
|
|||
import static org.springdoc.core.fn.builders.apiresponse.Builder.responseBuilder;
|
||||
import static org.springdoc.core.fn.builders.content.Builder.contentBuilder;
|
||||
import static org.springdoc.core.fn.builders.schema.Builder.schemaBuilder;
|
||||
import static org.springframework.boot.convert.ApplicationConversionService.getSharedInstance;
|
||||
import static org.springframework.web.reactive.function.BodyExtractors.toMultipartData;
|
||||
import static org.springframework.web.reactive.function.server.RequestPredicates.contentType;
|
||||
import static run.halo.app.extension.ListResult.generateGenericClass;
|
||||
|
@ -168,6 +169,10 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
@Schema(description = "Name of group")
|
||||
Optional<String> getGroup();
|
||||
|
||||
@Schema(description = "Filter attachments without group. This parameter will ignore group"
|
||||
+ " parameter.")
|
||||
Optional<Boolean> getUngrouped();
|
||||
|
||||
@Schema(description = "Name of user who uploaded the attachment")
|
||||
Optional<String> getUploadedBy();
|
||||
|
||||
|
@ -209,6 +214,12 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
.filter(StringUtils::hasText);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Boolean> getUngrouped() {
|
||||
return Optional.ofNullable(queryParams.getFirst("ungrouped"))
|
||||
.map(ungroupedStr -> getSharedInstance().convert(ungroupedStr, Boolean.class));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getUploadedBy() {
|
||||
return Optional.ofNullable(queryParams.getFirst("uploadedBy"))
|
||||
|
@ -221,33 +232,49 @@ public class AttachmentEndpoint implements CustomEndpoint {
|
|||
}
|
||||
|
||||
public Predicate<Attachment> toPredicate() {
|
||||
var predicate = (Predicate<Attachment>) (attachment) -> getDisplayName()
|
||||
Predicate<Attachment> displayNamePred = attachment -> getDisplayName()
|
||||
.map(displayNameInParam -> {
|
||||
String displayName = attachment.getSpec().getDisplayName();
|
||||
return displayName.contains(displayNameInParam);
|
||||
}).orElse(true)
|
||||
&& getPolicy()
|
||||
}).orElse(true);
|
||||
|
||||
Predicate<Attachment> policyPred = attachment -> getPolicy()
|
||||
.map(policy -> {
|
||||
var policyRef = attachment.getSpec().getPolicyRef();
|
||||
return policyRef != null && policy.equals(policyRef.getName());
|
||||
}).orElse(true)
|
||||
&& getGroup()
|
||||
}).orElse(true);
|
||||
|
||||
Predicate<Attachment> groupPred = attachment -> getGroup()
|
||||
.map(group -> {
|
||||
var groupRef = attachment.getSpec().getGroupRef();
|
||||
return groupRef != null && group.equals(groupRef.getName());
|
||||
})
|
||||
.orElse(true)
|
||||
&& getUploadedBy()
|
||||
.orElse(true);
|
||||
|
||||
Predicate<Attachment> ungroupedPred = attachment -> getUngrouped()
|
||||
.filter(Boolean::booleanValue)
|
||||
.map(ungrouped -> {
|
||||
var groupRef = attachment.getSpec().getGroupRef();
|
||||
return groupRef == null || !StringUtils.hasText(groupRef.getName());
|
||||
})
|
||||
.orElseGet(() -> groupPred.test(attachment));
|
||||
|
||||
Predicate<Attachment> uploadedByPred = attachment -> getUploadedBy()
|
||||
.map(uploadedBy -> {
|
||||
var uploadedByRef = attachment.getSpec().getUploadedBy();
|
||||
return uploadedByRef != null && uploadedBy.equals(uploadedByRef.getName());
|
||||
})
|
||||
.orElse(true);
|
||||
|
||||
var selectorPredicate = labelAndFieldSelectorToPredicate(getLabelSelector(),
|
||||
getFieldSelector());
|
||||
|
||||
return predicate.and(selectorPredicate);
|
||||
var selectorPred =
|
||||
labelAndFieldSelectorToPredicate(getLabelSelector(), getFieldSelector());
|
||||
|
||||
return displayNamePred
|
||||
.and(policyPred)
|
||||
.and(ungroupedPred)
|
||||
.and(uploadedByPred)
|
||||
.and(selectorPred);
|
||||
}
|
||||
|
||||
public Comparator<Attachment> toComparator() {
|
||||
|
|
|
@ -1,6 +1,10 @@
|
|||
package run.halo.app.core.extension.attachment.endpoint;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.assertFalse;
|
||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.same;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
@ -18,13 +22,19 @@ import org.mockito.Mock;
|
|||
import org.mockito.junit.jupiter.MockitoExtension;
|
||||
import org.springframework.http.MediaType;
|
||||
import org.springframework.http.client.MultipartBodyBuilder;
|
||||
import org.springframework.mock.http.server.reactive.MockServerHttpRequest;
|
||||
import org.springframework.mock.web.reactive.function.server.MockServerRequest;
|
||||
import org.springframework.mock.web.server.MockServerWebExchange;
|
||||
import org.springframework.test.web.reactive.server.WebTestClient;
|
||||
import org.springframework.web.reactive.function.BodyInserters;
|
||||
import reactor.core.publisher.Mono;
|
||||
import run.halo.app.core.extension.attachment.Attachment;
|
||||
import run.halo.app.core.extension.attachment.Attachment.AttachmentSpec;
|
||||
import run.halo.app.core.extension.attachment.Policy;
|
||||
import run.halo.app.core.extension.attachment.Policy.PolicySpec;
|
||||
import run.halo.app.core.extension.attachment.endpoint.AttachmentEndpoint.SearchRequest;
|
||||
import run.halo.app.extension.ConfigMap;
|
||||
import run.halo.app.extension.ListResult;
|
||||
import run.halo.app.extension.Metadata;
|
||||
import run.halo.app.extension.ReactiveExtensionClient;
|
||||
import run.halo.app.extension.Ref;
|
||||
|
@ -149,4 +159,45 @@ class AttachmentEndpointTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
class SearchTest {
|
||||
|
||||
@Test
|
||||
void shouldListUngroupedAttachments() {
|
||||
when(client.list(same(Attachment.class), any(), any(), anyInt(), anyInt()))
|
||||
.thenReturn(Mono.just(ListResult.emptyResult()));
|
||||
|
||||
webClient
|
||||
.get()
|
||||
.uri("/attachments")
|
||||
.exchange()
|
||||
.expectStatus().isOk()
|
||||
.expectBody()
|
||||
.jsonPath("items.length()").isEqualTo(0);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldFilterWithUngrouped() {
|
||||
var httpRequest = MockServerHttpRequest.get("/attachments")
|
||||
.build();
|
||||
var exchange = new MockServerWebExchange.Builder(httpRequest)
|
||||
.build();
|
||||
MockServerRequest request = MockServerRequest.builder()
|
||||
.queryParam("ungrouped", "true")
|
||||
.queryParam("group", "halo")
|
||||
.exchange(exchange)
|
||||
.build();
|
||||
var searchRequest = new SearchRequest(request);
|
||||
var pred = searchRequest.toPredicate();
|
||||
var attachment = new Attachment();
|
||||
var spec = new AttachmentSpec();
|
||||
attachment.setSpec(spec);
|
||||
|
||||
assertTrue(pred.test(attachment));
|
||||
|
||||
spec.setGroupRef(Ref.of("halo"));
|
||||
assertFalse(pred.test(attachment));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue