Skip to content

Commit 10d93ae

Browse files
nikolinaspeharivicac
authored andcommitted
2316 - trigger logic improved
1 parent 897c9f9 commit 10d93ae

3 files changed

Lines changed: 33 additions & 21 deletions

File tree

server/libs/modules/components/google/youtube/src/main/java/com/bytechef/component/youtube/constant/YoutubeConstants.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ public class YoutubeConstants {
2727
public static final String ID = "id";
2828
public static final String IDENTIFIER = "identifier";
2929
public static final String ITEMS = "items";
30+
public static final String LAST_TIME_CHECKED = "lastTimeChecked";
3031
public static final String LOCATION = "location";
3132
public static final String PRIVACY_STATUS = "privacyStatus";
3233
public static final String SNIPPET = "snippet";

server/libs/modules/components/google/youtube/src/main/java/com/bytechef/component/youtube/trigger/YoutubeNewVideoTrigger.java

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,10 @@
2121
import static com.bytechef.component.definition.ComponentDsl.outputSchema;
2222
import static com.bytechef.component.definition.ComponentDsl.string;
2323
import static com.bytechef.component.definition.ComponentDsl.trigger;
24-
import static com.bytechef.component.youtube.constant.YoutubeConstants.ID;
2524
import static com.bytechef.component.youtube.constant.YoutubeConstants.IDENTIFIER;
2625
import static com.bytechef.component.youtube.constant.YoutubeConstants.ITEMS;
26+
import static com.bytechef.component.youtube.constant.YoutubeConstants.LAST_TIME_CHECKED;
2727
import static com.bytechef.component.youtube.constant.YoutubeConstants.SNIPPET;
28-
import static com.bytechef.component.youtube.constant.YoutubeConstants.VIDEO;
2928
import static com.bytechef.component.youtube.util.YoutubeUtils.getChannelId;
3029

3130
import com.bytechef.component.definition.ComponentDsl.ModifiableTriggerDefinition;
@@ -36,6 +35,10 @@
3635
import com.bytechef.component.definition.TriggerDefinition.PollOutput;
3736
import com.bytechef.component.definition.TriggerDefinition.TriggerType;
3837
import com.bytechef.component.definition.TypeReference;
38+
import java.time.LocalDateTime;
39+
import java.time.ZoneId;
40+
import java.time.ZonedDateTime;
41+
import java.time.format.DateTimeFormatter;
3942
import java.util.ArrayList;
4043
import java.util.List;
4144
import java.util.Map;
@@ -111,18 +114,23 @@ protected static PollOutput poll(
111114
Parameters inputParameters, Parameters connectionParameters, Parameters closureParameters,
112115
TriggerContext triggerContext) {
113116

114-
List<String> allVideos = closureParameters.getList(VIDEO, String.class, List.of());
115-
List<String> allVideosUpdated = new ArrayList<>();
116-
117117
String channelId = getChannelId(inputParameters.getRequiredString(IDENTIFIER), triggerContext);
118118

119+
ZoneId zoneId = ZoneId.systemDefault();
120+
121+
LocalDateTime now = LocalDateTime.now(zoneId);
122+
123+
LocalDateTime startDate = closureParameters.getLocalDateTime(LAST_TIME_CHECKED, now.minusHours(3));
124+
ZonedDateTime startZonedDate = startDate.atZone(zoneId);
125+
119126
Map<String, Object> response =
120127
triggerContext.http(http -> http.get("https://www.googleapis.com/youtube/v3/search"))
121128
.queryParameters(
122129
"part", SNIPPET,
123130
"channelId", channelId,
124131
"type", "video",
125-
"order", "date")
132+
"order", "date",
133+
"publishedAfter", startZonedDate.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME))
126134
.configuration(Http.responseType(ResponseType.JSON))
127135
.execute()
128136
.getBody(new TypeReference<>() {});
@@ -132,19 +140,13 @@ protected static PollOutput poll(
132140
if (response.get(ITEMS) instanceof List<?> items) {
133141
for (Object item : items) {
134142
if (item instanceof Map<?, ?> itemMap &&
135-
itemMap.get(ID) instanceof Map<?, ?> idMap &&
136-
idMap.get("videoId") instanceof String videoId &&
137143
itemMap.get(SNIPPET) instanceof Map<?, ?> snippet) {
138144

139-
allVideosUpdated.add(videoId);
140-
141-
if (!allVideos.contains(videoId)) {
142-
newVideos.add(snippet);
143-
}
145+
newVideos.add(snippet);
144146
}
145147
}
146148
}
147149

148-
return new PollOutput(newVideos, Map.of(VIDEO, allVideosUpdated), false);
150+
return new PollOutput(newVideos, Map.of(LAST_TIME_CHECKED, now), false);
149151
}
150152
}

server/libs/modules/components/google/youtube/src/test/java/com/bytechef/component/youtube/trigger/YoutubeNewVideoTriggerTest.java

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,10 @@
1717
package com.bytechef.component.youtube.trigger;
1818

1919
import static com.bytechef.component.youtube.constant.YoutubeConstants.IDENTIFIER;
20-
import static com.bytechef.component.youtube.constant.YoutubeConstants.VIDEO;
20+
import static com.bytechef.component.youtube.constant.YoutubeConstants.LAST_TIME_CHECKED;
2121
import static org.junit.jupiter.api.Assertions.assertArrayEquals;
2222
import static org.junit.jupiter.api.Assertions.assertEquals;
23+
import static org.junit.jupiter.api.Assertions.assertFalse;
2324
import static org.mockito.ArgumentMatchers.any;
2425
import static org.mockito.Mockito.mock;
2526
import static org.mockito.Mockito.mockStatic;
@@ -32,6 +33,10 @@
3233
import com.bytechef.component.definition.TypeReference;
3334
import com.bytechef.component.test.definition.MockParametersFactory;
3435
import com.bytechef.component.youtube.util.YoutubeUtils;
36+
import java.time.LocalDateTime;
37+
import java.time.ZoneId;
38+
import java.time.ZonedDateTime;
39+
import java.time.format.DateTimeFormatter;
3540
import java.util.List;
3641
import java.util.Map;
3742
import org.junit.jupiter.api.Test;
@@ -44,15 +49,17 @@
4449
class YoutubeNewVideoTriggerTest {
4550

4651
private final Http.Executor mockedExecutor = mock(Http.Executor.class);
47-
private final Parameters mockedParameters = MockParametersFactory.create(Map.of(IDENTIFIER, "testIdentifier"));
4852
private final Http.Response mockedResponse = mock(Http.Response.class);
4953
private final TriggerContext mockedTriggerContext = mock(TriggerContext.class);
54+
private final LocalDateTime mockLocalDate = LocalDateTime.of(2025, 6, 16, 15, 5);
5055
private final ArgumentCaptor<Object[]> queryArgumentCaptor = ArgumentCaptor.forClass(Object[].class);
5156
private final Map<String, Object> responseMap = Map.of("items", List.of(
5257
Map.of("id", Map.of("videoId", "1"), "snippet", Map.of())));
5358
private final ArgumentCaptor<String> stringArgumentCaptor = ArgumentCaptor.forClass(String.class);
5459
private final ArgumentCaptor<TriggerContext> triggerContextArgumentCaptor =
5560
ArgumentCaptor.forClass(TriggerContext.class);
61+
private final Parameters mockedParameters =
62+
MockParametersFactory.create(Map.of(IDENTIFIER, "testIdentifier", LAST_TIME_CHECKED, mockLocalDate));
5663

5764
@Test
5865
void testPoll() {
@@ -75,20 +82,22 @@ void testPoll() {
7582
PollOutput pollOutput = YoutubeNewVideoTrigger.poll(
7683
mockedParameters, mockedParameters, mockedParameters, mockedTriggerContext);
7784

78-
PollOutput expectedPollOutput = new PollOutput(
79-
List.of(Map.of()), Map.of(VIDEO, List.of("1")), false);
80-
81-
assertEquals(expectedPollOutput, pollOutput);
85+
assertEquals(List.of(Map.of()), pollOutput.records());
86+
assertFalse(pollOutput.pollImmediately());
8287

8388
assertEquals("testIdentifier", stringArgumentCaptor.getValue());
8489
assertEquals(mockedTriggerContext, triggerContextArgumentCaptor.getValue());
8590

91+
ZoneId zoneId = ZoneId.systemDefault();
92+
ZonedDateTime startZonedDate = mockLocalDate.atZone(zoneId);
93+
8694
Object[] queryArguments = queryArgumentCaptor.getValue();
8795
Object[] expectedQueryArguments = {
8896
"part", "snippet",
8997
"channelId", "channelId",
9098
"type", "video",
91-
"order", "date"
99+
"order", "date",
100+
"publishedAfter", startZonedDate.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME)
92101
};
93102

94103
assertArrayEquals(expectedQueryArguments, queryArguments);

0 commit comments

Comments
 (0)