From 01ee354801b49be1dd7285ce4f1dbe7b8ddbf3cc Mon Sep 17 00:00:00 2001 From: "Jessie (Xiaoyu) Jiang" <70290069+jessiexjiang27@users.noreply.github.com> Date: Fri, 11 Sep 2020 18:25:32 -0400 Subject: [PATCH] samples: add samples for Dialogflow CX (#15) * Add sample codes. Add the sample codes for the following method: - CreateFlow - CreatePage - CreateIntent - DetectIntent - StreamingDetectIntent * Small fix to header Small fix to header to pass lint * Fix package name Fix package format. * Add tests for sample codes. Add tests for sample codes per change request. * Fix lint error. Change the location of variable declarations. * Exclude new dependencies from the region tag Exclude new dependencies from the region tag * Add integration tests for sample codes. Add integration tests for sample codes. * Change env vars and package based on comments Change the env variables and package names based on comments. Remove DIALOGFLOW_CX_AGENT_ID from Kokora configs. * Refactor code and move clean up logics * Change output stream Avoid setting output stream to null to enable tests to run in parallel. * Get audio transcript for test --- .../snippets/resources/book_a_room.wav | Bin 0 -> 31058 bytes .../main/java/dialogflow/cx/CreateFlow.java | 79 ++++++++++++ .../main/java/dialogflow/cx/CreateIntent.java | 72 +++++++++++ .../main/java/dialogflow/cx/CreatePage.java | 101 ++++++++++++++++ .../main/java/dialogflow/cx/DetectIntent.java | 87 ++++++++++++++ .../dialogflow/cx/DetectIntentStream.java | 112 ++++++++++++++++++ .../test/java/dialogflow/cx/CreateFlowIT.java | 67 +++++++++++ .../java/dialogflow/cx/CreateIntentIT.java | 71 +++++++++++ .../test/java/dialogflow/cx/CreatePageIT.java | 66 +++++++++++ .../java/dialogflow/cx/DetectIntentIT.java | 54 +++++++++ .../dialogflow/cx/DetectIntentStreamIT.java | 69 +++++++++++ 11 files changed, 778 insertions(+) create mode 100644 dialogflow-cx/snippets/resources/book_a_room.wav create mode 100644 dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateFlow.java create mode 100644 dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateIntent.java create mode 100644 dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreatePage.java create mode 100644 dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntent.java create mode 100644 dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntentStream.java create mode 100644 dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateFlowIT.java create mode 100644 dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateIntentIT.java create mode 100644 dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreatePageIT.java create mode 100644 dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentIT.java create mode 100644 dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentStreamIT.java diff --git a/dialogflow-cx/snippets/resources/book_a_room.wav b/dialogflow-cx/snippets/resources/book_a_room.wav new file mode 100644 index 0000000000000000000000000000000000000000..9124e9279460a0057df91202a5d0e5e147b60813 GIT binary patch literal 31058 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 Nh$0A1lK;Pd{tuoqdJX^p literal 0 HcmV?d00001 diff --git a/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateFlow.java b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateFlow.java new file mode 100644 index 00000000000..90ff3eae318 --- /dev/null +++ b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateFlow.java @@ -0,0 +1,79 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +// [START dialogflow_cx_create_flow] + +import com.google.api.gax.rpc.ApiException; +import com.google.cloud.dialogflow.cx.v3beta1.AgentName; +import com.google.cloud.dialogflow.cx.v3beta1.EventHandler; +import com.google.cloud.dialogflow.cx.v3beta1.Flow; +import com.google.cloud.dialogflow.cx.v3beta1.FlowsClient; +import com.google.cloud.dialogflow.cx.v3beta1.Fulfillment; +import com.google.cloud.dialogflow.cx.v3beta1.ResponseMessage; +import com.google.cloud.dialogflow.cx.v3beta1.ResponseMessage.Text; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + +public class CreateFlow { + + // Create a flow in the specified agent. + public static Flow createFlow( + String displayName, + String projectId, + String locationId, + String agentId, + Map eventsToFulfillmentMessages) + throws IOException, ApiException { + // Instantiates a client + try (FlowsClient flowsClient = FlowsClient.create()) { + // Set the project agent name using the projectID (my-project-id), locationID (global), and + // agentID (UUID). + AgentName parent = AgentName.of(projectId, locationId, agentId); + + // Build the EventHandlers for the flow using the mapping from events to fulfillment messages. + List eventHandlers = new ArrayList<>(); + for (Map.Entry item : eventsToFulfillmentMessages.entrySet()) { + eventHandlers.add( + EventHandler.newBuilder() + .setEvent(item.getKey()) // Event (sys.no-match-default) + .setTriggerFulfillment( + Fulfillment.newBuilder() + // Text ("Sorry, could you say that again?") + .addMessages( + ResponseMessage.newBuilder() + .setText(Text.newBuilder().addText(item.getValue()).build()) + .build()) + .build()) + .build()); + } + + // Build the flow. + Flow flow = + Flow.newBuilder().setDisplayName(displayName).addAllEventHandlers(eventHandlers).build(); + + // Performs the create flow request. + Flow response = flowsClient.createFlow(parent, flow); + System.out.format("Flow created: %s\n", response); + + return response; + } + } +} +// [END dialogflow_cx_create_flow] diff --git a/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateIntent.java b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateIntent.java new file mode 100644 index 00000000000..6aca7382b45 --- /dev/null +++ b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreateIntent.java @@ -0,0 +1,72 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +// [START dialogflow_cx_create_intent] + +import com.google.api.gax.rpc.ApiException; +import com.google.cloud.dialogflow.cx.v3beta1.AgentName; +import com.google.cloud.dialogflow.cx.v3beta1.Intent; +import com.google.cloud.dialogflow.cx.v3beta1.Intent.TrainingPhrase; +import com.google.cloud.dialogflow.cx.v3beta1.Intent.TrainingPhrase.Part; +import com.google.cloud.dialogflow.cx.v3beta1.IntentsClient; +import java.io.IOException; +import java.util.ArrayList; +import java.util.List; + +public class CreateIntent { + + // Create an intent of the given intent type. + public static Intent createIntent( + String displayName, + String projectId, + String locationId, + String agentId, + List trainingPhrasesParts) + throws IOException, ApiException { + // Instantiates a client + try (IntentsClient intentsClient = IntentsClient.create()) { + // Set the project agent name using the projectID (my-project-id), locationID (global), and + // agentID (UUID). + AgentName parent = AgentName.of(projectId, locationId, agentId); + + // Build the trainingPhrases from the trainingPhrasesParts. + List trainingPhrases = new ArrayList<>(); + for (String trainingPhrase : trainingPhrasesParts) { + trainingPhrases.add( + TrainingPhrase.newBuilder() + .addParts(Part.newBuilder().setText(trainingPhrase).build()) + .setRepeatCount(1) + .build()); + } + + // Build the intent. + Intent intent = + Intent.newBuilder() + .setDisplayName(displayName) + .addAllTrainingPhrases(trainingPhrases) + .build(); + + // Performs the create intent request. + Intent response = intentsClient.createIntent(parent, intent); + System.out.format("Intent created: %s\n", response); + + return response; + } + } +} +// [END dialogflow_cx_create_intent] diff --git a/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreatePage.java b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreatePage.java new file mode 100644 index 00000000000..8b9688521f8 --- /dev/null +++ b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/CreatePage.java @@ -0,0 +1,101 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +// [START dialogflow_cx_create_page] + +import com.google.api.gax.rpc.ApiException; +import com.google.cloud.dialogflow.cx.v3beta1.FlowName; +import com.google.cloud.dialogflow.cx.v3beta1.Form; +import com.google.cloud.dialogflow.cx.v3beta1.Form.Parameter; +import com.google.cloud.dialogflow.cx.v3beta1.Form.Parameter.FillBehavior; +import com.google.cloud.dialogflow.cx.v3beta1.Fulfillment; +import com.google.cloud.dialogflow.cx.v3beta1.Page; +import com.google.cloud.dialogflow.cx.v3beta1.PagesClient; +import com.google.cloud.dialogflow.cx.v3beta1.ResponseMessage; +import com.google.cloud.dialogflow.cx.v3beta1.ResponseMessage.Text; +import java.io.IOException; +import java.util.List; + +public class CreatePage { + + // Create a page in the specified agent. + public static Page createPage( + String displayName, + String projectId, + String locationId, + String agentId, + String flowId, + List entryTexts) + throws IOException, ApiException { + // Instantiates a client + try (PagesClient pagesClient = PagesClient.create()) { + // Set the flow name using the projectID (my-project-id), locationID (global), agentID (UUID) + // and flowID (UUID). + FlowName parent = FlowName.of(projectId, locationId, agentId, flowId); + + // Build the entry fulfillment based on entry texts. + Fulfillment.Builder entryFulfillmentBuilder = Fulfillment.newBuilder(); + for (String entryText : entryTexts) { + entryFulfillmentBuilder.addMessages( + ResponseMessage.newBuilder() + // Text ("Hi") + .setText(Text.newBuilder().addText(entryText).build()) + .build()); + } + Fulfillment entryFulfillment = entryFulfillmentBuilder.build(); + + // Build the form for the new page. + // Note: hard coding parameters for simplicity. + FillBehavior fillBehavior = + FillBehavior.newBuilder() + .setInitialPromptFulfillment( + Fulfillment.newBuilder() + .addMessages( + ResponseMessage.newBuilder() + .setText(Text.newBuilder().addText("What would you like?").build()) + .build()) + .build()) + .build(); + Form form = + Form.newBuilder() + .addParameters( + Parameter.newBuilder() + .setDisplayName("param") + .setRequired(true) + .setEntityType("projects/-/locations/-/agents/-/entityTypes/sys.any") + .setFillBehavior(fillBehavior) + .build()) + .build(); + + // Build the page. + Page page = + Page.newBuilder() + .setDisplayName(displayName) + .setEntryFulfillment(entryFulfillment) + .setForm(form) + .build(); + + // Performs the create page request. + Page response = pagesClient.createPage(parent, page); + System.out.format("Page created: %s\n", response); + + return response; + } + } +} +// [END dialogflow_cx_create_page] diff --git a/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntent.java b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntent.java new file mode 100644 index 00000000000..94dffb8f3b1 --- /dev/null +++ b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntent.java @@ -0,0 +1,87 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +// [START dialogflow_cx_detect_intent_text] + +import com.google.api.gax.rpc.ApiException; +import com.google.cloud.dialogflow.cx.v3beta1.DetectIntentRequest; +import com.google.cloud.dialogflow.cx.v3beta1.DetectIntentResponse; +import com.google.cloud.dialogflow.cx.v3beta1.QueryInput; +import com.google.cloud.dialogflow.cx.v3beta1.QueryResult; +import com.google.cloud.dialogflow.cx.v3beta1.SessionName; +import com.google.cloud.dialogflow.cx.v3beta1.SessionsClient; +import com.google.cloud.dialogflow.cx.v3beta1.TextInput; +import com.google.common.collect.Maps; +import java.io.IOException; +import java.util.List; +import java.util.Map; + +public class DetectIntent { + + // DialogFlow API Detect Intent sample with text inputs. + public static Map detectIntent( + String projectId, + String locationId, + String agentId, + String sessionId, + List texts, + String languageCode) + throws IOException, ApiException { + Map queryResults = Maps.newHashMap(); + // Instantiates a client + try (SessionsClient sessionsClient = SessionsClient.create()) { + // Set the session name using the projectID (my-project-id), locationID (global), agentID + // (UUID), and sessionId (UUID). + SessionName session = SessionName.of(projectId, locationId, agentId, sessionId); + System.out.println("Session Path: " + session.toString()); + + // Detect intents for each text input. + for (String text : texts) { + // Set the text (hello) for the query. + TextInput.Builder textInput = TextInput.newBuilder().setText(text); + + // Build the query with the TextInput and language code (en-US). + QueryInput queryInput = + QueryInput.newBuilder().setText(textInput).setLanguageCode(languageCode).build(); + + // Build the DetectIntentRequest with the SessionName and QueryInput. + DetectIntentRequest request = + DetectIntentRequest.newBuilder() + .setSession(session.toString()) + .setQueryInput(queryInput) + .build(); + + // Performs the detect intent request. + DetectIntentResponse response = sessionsClient.detectIntent(request); + + // Display the query result. + QueryResult queryResult = response.getQueryResult(); + + System.out.println("===================="); + System.out.format("Query Text: '%s'\n", queryResult.getText()); + System.out.format( + "Detected Intent: %s (confidence: %f)\n", + queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence()); + + queryResults.put(text, queryResult); + } + } + return queryResults; + } +} +// [END dialogflow_cx_detect_intent_text] diff --git a/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntentStream.java b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntentStream.java new file mode 100644 index 00000000000..3bab80a0150 --- /dev/null +++ b/dialogflow-cx/snippets/src/main/java/dialogflow/cx/DetectIntentStream.java @@ -0,0 +1,112 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +// [START dialogflow_cx_detect_intent_streaming] + +import com.google.api.gax.rpc.ApiException; +import com.google.api.gax.rpc.BidiStream; +import com.google.cloud.dialogflow.cx.v3beta1.AudioEncoding; +import com.google.cloud.dialogflow.cx.v3beta1.AudioInput; +import com.google.cloud.dialogflow.cx.v3beta1.InputAudioConfig; +import com.google.cloud.dialogflow.cx.v3beta1.QueryInput; +import com.google.cloud.dialogflow.cx.v3beta1.QueryResult; +import com.google.cloud.dialogflow.cx.v3beta1.SessionName; +import com.google.cloud.dialogflow.cx.v3beta1.SessionsClient; +import com.google.cloud.dialogflow.cx.v3beta1.StreamingDetectIntentRequest; +import com.google.cloud.dialogflow.cx.v3beta1.StreamingDetectIntentResponse; +import com.google.protobuf.ByteString; +import java.io.FileInputStream; +import java.io.IOException; + +public class DetectIntentStream { + + // DialogFlow API Detect Intent sample with audio files processes as an audio stream. + public static void detectIntentStream( + String projectId, String locationId, String agentId, String sessionId, String audioFilePath) + throws ApiException, IOException { + // Instantiates a client + try (SessionsClient sessionsClient = SessionsClient.create()) { + // Set the session name using the projectID (my-project-id), locationID (global), agentID + // (UUID), and sessionId (UUID). + // Using the same `sessionId` between requests allows continuation of the conversation. + SessionName session = SessionName.of(projectId, locationId, agentId, sessionId); + + // Instructs the speech recognizer how to process the audio content. + // Note: hard coding audioEncoding and sampleRateHertz for simplicity. + // Audio encoding of the audio content sent in the query request. + InputAudioConfig inputAudioConfig = + InputAudioConfig.newBuilder() + .setAudioEncoding(AudioEncoding.AUDIO_ENCODING_LINEAR_16) + .setSampleRateHertz(16000) // sampleRateHertz = 16000 + .build(); + + // Build the AudioInput with the InputAudioConfig. + AudioInput audioInput = AudioInput.newBuilder().setConfig(inputAudioConfig).build(); + + // Build the query with the InputAudioConfig. + QueryInput queryInput = + QueryInput.newBuilder() + .setAudio(audioInput) + .setLanguageCode("en-US") // languageCode = "en-US" + .build(); + + // Create the Bidirectional stream + BidiStream bidiStream = + sessionsClient.streamingDetectIntentCallable().call(); + + // The first request must **only** contain the audio configuration: + bidiStream.send( + StreamingDetectIntentRequest.newBuilder() + .setSession(session.toString()) + .setQueryInput(queryInput) + .build()); + + try (FileInputStream audioStream = new FileInputStream(audioFilePath)) { + // Subsequent requests must **only** contain the audio data. + // Following messages: audio chunks. We just read the file in fixed-size chunks. In reality + // you would split the user input by time. + byte[] buffer = new byte[4096]; + int bytes; + while ((bytes = audioStream.read(buffer)) != -1) { + AudioInput subAudioInput = + AudioInput.newBuilder().setAudio(ByteString.copyFrom(buffer, 0, bytes)).build(); + QueryInput subQueryInput = + QueryInput.newBuilder() + .setAudio(subAudioInput) + .setLanguageCode("en-US") // languageCode = "en-US" + .build(); + bidiStream.send( + StreamingDetectIntentRequest.newBuilder().setQueryInput(subQueryInput).build()); + } + } + + // Tell the service you are done sending data. + bidiStream.closeSend(); + + for (StreamingDetectIntentResponse response : bidiStream) { + QueryResult queryResult = response.getDetectIntentResponse().getQueryResult(); + System.out.println("===================="); + System.out.format("Query Text: '%s'\n", queryResult.getTranscript()); + System.out.format( + "Detected Intent: %s (confidence: %f)\n", + queryResult.getIntent().getDisplayName(), queryResult.getIntentDetectionConfidence()); + } + } + } +} +// [END dialogflow_cx_detect_intent_streaming] diff --git a/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateFlowIT.java b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateFlowIT.java new file mode 100644 index 00000000000..f5356828bbc --- /dev/null +++ b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateFlowIT.java @@ -0,0 +1,67 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +import static org.junit.Assert.assertEquals; + +import com.google.cloud.dialogflow.cx.v3beta1.Flow; +import com.google.cloud.dialogflow.cx.v3beta1.FlowsClient; +import com.google.common.collect.ImmutableMap; +import java.util.Map; +import java.util.UUID; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link CreateFlow}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class CreateFlowIT { + + private static String DISPLAY_NAME = "flow-" + UUID.randomUUID().toString(); + private static String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static String LOCATION = "global"; + private static String AGENT_ID = + System.getenv() + .getOrDefault("DIALOGFLOW_CX_AGENT_ID", "b8d0e85d-0741-4e6d-a66a-3671184b7b93"); + private static Map EVENT_TO_FULFILLMENT_MESSAGES = + ImmutableMap.of("event-1", "message-1", "event-2", "message-2"); + private static String newFlowName; + + @After + public void tearDown() throws Exception { + // Delete the newly created Flow. + if (newFlowName != null) { + try (FlowsClient flowsClient = FlowsClient.create()) { + flowsClient.deleteFlow(newFlowName); + } + } + } + + @Test + public void testCreateFlow() throws Exception { + Flow result = + CreateFlow.createFlow( + DISPLAY_NAME, PROJECT_ID, LOCATION, AGENT_ID, EVENT_TO_FULFILLMENT_MESSAGES); + newFlowName = result.getName(); + + assertEquals(result.getDisplayName(), DISPLAY_NAME); + // Number of added event handlers + 2 default event handlers. + assertEquals(result.getEventHandlersCount(), EVENT_TO_FULFILLMENT_MESSAGES.size() + 2); + } +} diff --git a/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateIntentIT.java b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateIntentIT.java new file mode 100644 index 00000000000..67580d3c4f5 --- /dev/null +++ b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreateIntentIT.java @@ -0,0 +1,71 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +import com.google.cloud.dialogflow.cx.v3beta1.Intent; +import com.google.cloud.dialogflow.cx.v3beta1.Intent.TrainingPhrase; +import com.google.cloud.dialogflow.cx.v3beta1.IntentsClient; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link CreateIntent}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class CreateIntentIT { + + private static String DISPLAY_NAME = "intent-" + UUID.randomUUID().toString(); + private static String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static String LOCATION = "global"; + private static String AGENT_ID = + System.getenv() + .getOrDefault("DIALOGFLOW_CX_AGENT_ID", "b8d0e85d-0741-4e6d-a66a-3671184b7b93"); + private static List TRAINING_PHRASES_PARTS = Arrays.asList("red", "blue", "green"); + private static String newIntentName; + + @After + public void tearDown() throws Exception { + // Delete the newly created Intent. + if (newIntentName != null) { + try (IntentsClient intentsClient = IntentsClient.create()) { + intentsClient.deleteIntent(newIntentName); + } + } + } + + @Test + public void testCreateIntent() throws Exception { + Intent result = + CreateIntent.createIntent( + DISPLAY_NAME, PROJECT_ID, LOCATION, AGENT_ID, TRAINING_PHRASES_PARTS); + newIntentName = result.getName(); + + assertEquals(result.getTrainingPhrasesCount(), TRAINING_PHRASES_PARTS.size()); + for (TrainingPhrase trainingPhrase : result.getTrainingPhrasesList()) { + assertEquals(trainingPhrase.getPartsCount(), 1); + String partText = trainingPhrase.getParts(0).getText(); + assertTrue(partText.equals("red") || partText.equals("blue") || partText.equals("green")); + } + } +} diff --git a/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreatePageIT.java b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreatePageIT.java new file mode 100644 index 00000000000..4b3c26601ad --- /dev/null +++ b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/CreatePageIT.java @@ -0,0 +1,66 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +import static org.junit.Assert.assertEquals; + +import com.google.cloud.dialogflow.cx.v3beta1.Page; +import com.google.cloud.dialogflow.cx.v3beta1.PagesClient; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; +import org.junit.After; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link CreatePage}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class CreatePageIT { + + private static String DISPLAY_NAME = "page-" + UUID.randomUUID().toString(); + private static String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static String LOCATION = "global"; + private static String AGENT_ID = + System.getenv() + .getOrDefault("DIALOGFLOW_CX_AGENT_ID", "b8d0e85d-0741-4e6d-a66a-3671184b7b93"); + private static String DEFAULT_START_FLOW_ID = "00000000-0000-0000-0000-000000000000"; + private static List ENTRY_TEXTS = Arrays.asList("Hi", "Hello", "How can I help you?"); + private static String newPageName; + + @After + public void tearDown() throws Exception { + // Delete the newly created Page. + if (newPageName != null) { + try (PagesClient pagesClient = PagesClient.create()) { + pagesClient.deletePage(newPageName); + } + } + } + + @Test + public void testCreatePage() throws Exception { + Page result = + CreatePage.createPage( + DISPLAY_NAME, PROJECT_ID, LOCATION, AGENT_ID, DEFAULT_START_FLOW_ID, ENTRY_TEXTS); + newPageName = result.getName(); + + assertEquals(result.getDisplayName(), DISPLAY_NAME); + assertEquals(result.getEntryFulfillment().getMessagesCount(), ENTRY_TEXTS.size()); + } +} diff --git a/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentIT.java b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentIT.java new file mode 100644 index 00000000000..2a7e362a561 --- /dev/null +++ b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentIT.java @@ -0,0 +1,54 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +import static org.junit.Assert.assertEquals; + +import com.google.cloud.dialogflow.cx.v3beta1.QueryResult; +import java.util.Arrays; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link DetectIntent}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class DetectIntentIT { + + private static String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static String LOCATION = "global"; + private static String AGENT_ID = + System.getenv() + .getOrDefault("DIALOGFLOW_CX_AGENT_ID", "b8d0e85d-0741-4e6d-a66a-3671184b7b93"); + private static String SESSION_ID = UUID.randomUUID().toString(); + private static String LANGUAGE_CODE = "en-US"; + private static List TEXTS = Arrays.asList("hello", "book a meeting room"); + + @Test + public void testDetectIntent() throws Exception { + Map queryResults = + DetectIntent.detectIntent(PROJECT_ID, LOCATION, AGENT_ID, SESSION_ID, TEXTS, LANGUAGE_CODE); + assertEquals(queryResults.size(), TEXTS.size()); + for (int i = 0; i < TEXTS.size(); i++) { + String text = TEXTS.get(i); + assertEquals(queryResults.get(text).getText(), text); + } + } +} diff --git a/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentStreamIT.java b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentStreamIT.java new file mode 100644 index 00000000000..5a86c6e4fe9 --- /dev/null +++ b/dialogflow-cx/snippets/src/test/java/dialogflow/cx/DetectIntentStreamIT.java @@ -0,0 +1,69 @@ +/* + * Copyright 2020 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package dialogflow.cx; + +import static com.google.common.truth.Truth.assertThat; + +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.PrintStream; +import java.util.UUID; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +/** Integration (system) tests for {@link DetectIntentStream}. */ +@RunWith(JUnit4.class) +@SuppressWarnings("checkstyle:abbreviationaswordinname") +public class DetectIntentStreamIT { + + private static String AUDIO_FILE_PATH = "resources/book_a_room.wav"; + private static String PROJECT_ID = System.getenv("GOOGLE_CLOUD_PROJECT"); + private static String LOCATION = "global"; + private static String AGENT_ID = + System.getenv() + .getOrDefault("DIALOGFLOW_CX_AGENT_ID", "b8d0e85d-0741-4e6d-a66a-3671184b7b93"); + private static String SESSION_ID = UUID.randomUUID().toString(); + private ByteArrayOutputStream bout; + private PrintStream original; + + @Before + public void setUp() { + original = System.out; + bout = new ByteArrayOutputStream(); + System.setOut(new PrintStream(bout)); + } + + @After + public void tearDown() { + System.setOut(original); + bout.reset(); + } + + @Test + public void testDetectIntentStream() throws IOException { + DetectIntentStream.detectIntentStream( + PROJECT_ID, LOCATION, AGENT_ID, SESSION_ID, AUDIO_FILE_PATH); + + String output = bout.toString(); + + assertThat(output).contains("Detected Intent"); + assertThat(output).contains("book"); + } +}