/* * (C) Copyright IBM Corp. 2019, 2020. * * 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 com.ibm.watson.speech_to_text.v1; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import com.google.gson.Gson; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.ibm.cloud.sdk.core.http.HttpMediaType; import com.ibm.cloud.sdk.core.security.NoAuthAuthenticator; import com.ibm.cloud.sdk.core.util.GsonSingleton; import com.ibm.cloud.sdk.core.util.RequestUtils; import com.ibm.watson.common.TestUtils; import com.ibm.watson.common.WatsonServiceUnitTest; import com.ibm.watson.speech_to_text.v1.model.AcousticModel; import com.ibm.watson.speech_to_text.v1.model.AcousticModels; import com.ibm.watson.speech_to_text.v1.model.AddAudioOptions; import com.ibm.watson.speech_to_text.v1.model.AddCorpusOptions; import com.ibm.watson.speech_to_text.v1.model.AddGrammarOptions; import com.ibm.watson.speech_to_text.v1.model.AddWordOptions; import com.ibm.watson.speech_to_text.v1.model.AddWordsOptions; import com.ibm.watson.speech_to_text.v1.model.AudioListing; import com.ibm.watson.speech_to_text.v1.model.AudioResource; import com.ibm.watson.speech_to_text.v1.model.AudioResources; import com.ibm.watson.speech_to_text.v1.model.CheckJobOptions; import com.ibm.watson.speech_to_text.v1.model.Corpora; import com.ibm.watson.speech_to_text.v1.model.CreateAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.CreateJobOptions; import com.ibm.watson.speech_to_text.v1.model.CreateLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.CustomWord; import com.ibm.watson.speech_to_text.v1.model.DeleteAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteAudioOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteCorpusOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteGrammarOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteJobOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteUserDataOptions; import com.ibm.watson.speech_to_text.v1.model.DeleteWordOptions; import com.ibm.watson.speech_to_text.v1.model.GetAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.GetAudioOptions; import com.ibm.watson.speech_to_text.v1.model.GetCorpusOptions; import com.ibm.watson.speech_to_text.v1.model.GetGrammarOptions; import com.ibm.watson.speech_to_text.v1.model.GetLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.GetModelOptions; import com.ibm.watson.speech_to_text.v1.model.GetWordOptions; import com.ibm.watson.speech_to_text.v1.model.Grammar; import com.ibm.watson.speech_to_text.v1.model.Grammars; import com.ibm.watson.speech_to_text.v1.model.LanguageModel; import com.ibm.watson.speech_to_text.v1.model.LanguageModels; import com.ibm.watson.speech_to_text.v1.model.ListAcousticModelsOptions; import com.ibm.watson.speech_to_text.v1.model.ListAudioOptions; import com.ibm.watson.speech_to_text.v1.model.ListCorporaOptions; import com.ibm.watson.speech_to_text.v1.model.ListGrammarsOptions; import com.ibm.watson.speech_to_text.v1.model.ListLanguageModelsOptions; import com.ibm.watson.speech_to_text.v1.model.ListWordsOptions; import com.ibm.watson.speech_to_text.v1.model.RecognitionJob; import com.ibm.watson.speech_to_text.v1.model.RecognitionJobs; import com.ibm.watson.speech_to_text.v1.model.RecognizeOptions; import com.ibm.watson.speech_to_text.v1.model.RegisterCallbackOptions; import com.ibm.watson.speech_to_text.v1.model.RegisterStatus; import com.ibm.watson.speech_to_text.v1.model.ResetAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.ResetLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.SpeechModel; import com.ibm.watson.speech_to_text.v1.model.SpeechModels; import com.ibm.watson.speech_to_text.v1.model.SpeechRecognitionResult; import com.ibm.watson.speech_to_text.v1.model.SpeechRecognitionResults; import com.ibm.watson.speech_to_text.v1.model.TrainAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.TrainLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.UnregisterCallbackOptions; import com.ibm.watson.speech_to_text.v1.model.UpgradeAcousticModelOptions; import com.ibm.watson.speech_to_text.v1.model.UpgradeLanguageModelOptions; import com.ibm.watson.speech_to_text.v1.model.Word; import com.ibm.watson.speech_to_text.v1.model.Words; import com.ibm.watson.speech_to_text.v1.util.MediaTypeUtils; import com.ibm.watson.speech_to_text.v1.websocket.RecognizeCallback; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.net.URISyntaxException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import okhttp3.WebSocket; import okhttp3.internal.ws.WebSocketRecorder; import okhttp3.mockwebserver.MockResponse; import okhttp3.mockwebserver.RecordedRequest; import okio.ByteString; import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.FixMethodOrder; import org.junit.Test; import org.junit.runners.MethodSorters; /** The Class SpeechToTextTest. */ @FixMethodOrder(MethodSorters.JVM) public class SpeechToTextTest extends WatsonServiceUnitTest { private static final Gson GSON = GsonSingleton.getGsonWithoutPrettyPrinting(); private static final String PATH_CORPORA = "/v1/customizations/%s/corpora"; private static final String PATH_CORPUS = "/v1/customizations/%s/corpora/%s"; private static final String PATH_CUSTOMIZATION = "/v1/customizations/%s"; private static final String PATH_CUSTOMIZATIONS = "/v1/customizations"; private static final String PATH_ACOUSTIC_CUSTOMIZATION = "/v1/acoustic_customizations/%s"; private static final String PATH_ACOUSTIC_CUSTOMIZATIONS = "/v1/acoustic_customizations"; private static final String PATH_MODELS = "/v1/models"; private static final String PATH_RECOGNITION = "/v1/recognitions/%s"; private static final String PATH_RECOGNITIONS = "/v1/recognitions"; private static final String PATH_RECOGNIZE = "/v1/recognize"; private static final String PATH_ACOUSTIC_RESET = "/v1/acoustic_customizations/%s/reset"; private static final String PATH_RESET = "/v1/customizations/%s/reset"; private static final String PATH_ACOUSTIC_TRAIN = "/v1/acoustic_customizations/%s/train"; private static final String PATH_TRAIN = "/v1/customizations/%s/train"; private static final String PATH_WORDS = "/v1/customizations/%s/words"; private static final String PATH_WORD = "/v1/customizations/%s/words/%s"; private static final String PATH_ACOUSTIC_UPGRADE = "/v1/acoustic_customizations/%s/upgrade_model"; private static final String PATH_UPGRADE = "/v1/customizations/%s/upgrade_model"; private static final String PATH_ALL_AUDIO = "/v1/acoustic_customizations/%s/audio"; private static final String PATH_SPECIFIC_AUDIO = "/v1/acoustic_customizations/%s/audio/%s"; private static final String REGISTER_CALLBACK = "/v1/register_callback?callback_url=%s&user_secret=%s"; private static final String UNREGISTER_CALLBACK = "/v1/unregister_callback?callback_url=%s"; private static final File SAMPLE_WAV = new File("src/test/resources/speech_to_text/sample1.wav"); private static final File SAMPLE_WEBM = new File("src/test/resources/speech_to_text/sample1.webm"); private static final String UPDATED = "2019-10-11T19:16:58.547Z"; private SpeechModel speechModel; private SpeechModels speechModels; private SpeechRecognitionResults recognitionResults; private Grammars grammars; private Grammar grammar; private SpeechToText service; /** * Sets up the tests. * * @throws Exception the exception */ /* * (non-Javadoc) * @see com.ibm.watson.common.WatsonServiceTest#setUp() */ @Override @Before public void setUp() throws Exception { super.setUp(); service = new SpeechToText(new NoAuthAuthenticator()); service.setServiceUrl(getMockWebServerUrl()); speechModel = loadFixture("src/test/resources/speech_to_text/speech-model.json", SpeechModel.class); speechModels = loadFixture("src/test/resources/speech_to_text/speech-models.json", SpeechModels.class); recognitionResults = loadFixture( "src/test/resources/speech_to_text/recognition-results.json", SpeechRecognitionResults.class); grammars = loadFixture("src/test/resources/speech_to_text/grammar_list.json", Grammars.class); grammar = loadFixture("src/test/resources/speech_to_text/grammar.json", Grammar.class); } // --- MODELS --- /** Test delete user data options builder. */ @Test public void testDeleteUserDataOptionsBuilder() { String customerId = "customerId"; DeleteUserDataOptions deleteOptions = new DeleteUserDataOptions.Builder().customerId(customerId).build(); assertEquals(deleteOptions.customerId(), customerId); } /** * Test add grammar options. * * @throws FileNotFoundException the file not found exception */ @Test public void testAddGrammarOptions() throws FileNotFoundException { String customizationId = "id"; String grammarName = "grammar_name"; InputStream grammarFile = new FileInputStream(SAMPLE_WAV); AddGrammarOptions addGrammarOptions = new AddGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .grammarFile(grammarFile) .contentType("application/srgs") .allowOverwrite(true) .build(); assertEquals(customizationId, addGrammarOptions.customizationId()); assertEquals(grammarName, addGrammarOptions.grammarName()); assertEquals(grammarFile, addGrammarOptions.grammarFile()); assertEquals("application/srgs", addGrammarOptions.contentType()); assertTrue(addGrammarOptions.allowOverwrite()); } /** Test list grammars options. */ @Test public void testListGrammarsOptions() { String customizationId = "id"; ListGrammarsOptions listGrammarsOptions = new ListGrammarsOptions.Builder().customizationId(customizationId).build(); assertEquals(customizationId, listGrammarsOptions.customizationId()); } /** Test get grammar options. */ @Test public void testGetGrammarOptions() { String customizationId = "id"; String grammarName = "grammar_name"; GetGrammarOptions getGrammarOptions = new GetGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .build(); assertEquals(customizationId, getGrammarOptions.customizationId()); assertEquals(grammarName, getGrammarOptions.grammarName()); } /** Test delete grammar options. */ @Test public void testDeleteGrammarOptions() { String customizationId = "id"; String grammarName = "grammar_name"; DeleteGrammarOptions deleteGrammarOptions = new DeleteGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .build(); assertEquals(customizationId, deleteGrammarOptions.customizationId()); assertEquals(grammarName, deleteGrammarOptions.grammarName()); } // --- METHODS --- /** * Test get model. * * @throws Exception the exception */ @Test public void testGetModel() throws Exception { final MockResponse mockResponse = new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(speechModel)); server.enqueue(mockResponse); GetModelOptions getOptionsString = new GetModelOptions.Builder().modelId("not-a-real-Model").build(); SpeechModel model = service.getModel(getOptionsString).execute().getResult(); RecordedRequest request = server.takeRequest(); assertNotNull(model); assertEquals(model, speechModel); assertEquals(GET, request.getMethod()); server.enqueue(mockResponse); GetModelOptions getOptionsGetter = new GetModelOptions.Builder().modelId("not-a-real-Model").build(); model = service.getModel(getOptionsGetter).execute().getResult(); request = server.takeRequest(); assertNotNull(model); assertEquals(model, speechModel); assertEquals(GET, request.getMethod()); TestUtils.assertNoExceptionsOnGetters(model); } /** * Test get models. * * @throws InterruptedException the interrupted exception */ @Test public void testGetModels() throws InterruptedException { server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(speechModels))); final SpeechModels models = service.listModels().execute().getResult(); final RecordedRequest request = server.takeRequest(); assertNotNull(models); assertFalse(models.getModels().isEmpty()); assertEquals(models.getModels(), speechModels.getModels()); assertEquals(PATH_MODELS, request.getPath()); } /** Test get model with null. */ @Test(expected = IllegalArgumentException.class) public void testGetModelWithNull() { service.getModel(null).execute().getResult(); } /** * Test recognize. * * @throws URISyntaxException the URI syntax exception * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testRecognize() throws URISyntaxException, InterruptedException, FileNotFoundException { server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(recognitionResults))); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .audioMetrics(true) .endOfPhraseSilenceTime(2.0) .splitTranscriptAtPhraseEnd(true) .build(); assertEquals((Double) 2.0, recognizeOptions.endOfPhraseSilenceTime()); assertTrue(recognizeOptions.splitTranscriptAtPhraseEnd()); final SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertNotNull(result); assertEquals(result, recognitionResults); assertEquals("POST", request.getMethod()); assertEquals( PATH_RECOGNIZE + "?audio_metrics=true&end_of_phrase_silence_time=2.0&split_transcript_at_phrase_end=true", request.getPath()); assertEquals(HttpMediaType.AUDIO_WAV, request.getHeader(CONTENT_TYPE)); assertEquals( recognitionResults.getAudioMetrics().getSamplingInterval(), result.getAudioMetrics().getSamplingInterval()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().isXFinal(), result.getAudioMetrics().getAccumulated().isXFinal()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getEndTime(), result.getAudioMetrics().getAccumulated().getEndTime()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getSpeechRatio(), result.getAudioMetrics().getAccumulated().getSpeechRatio()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getHighFrequencyLoss(), result.getAudioMetrics().getAccumulated().getHighFrequencyLoss()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getSignalToNoiseRatio(), result.getAudioMetrics().getAccumulated().getSignalToNoiseRatio()); assertEquals( recognitionResults .getAudioMetrics() .getAccumulated() .getDirectCurrentOffset() .get(0) .getBegin(), result.getAudioMetrics().getAccumulated().getDirectCurrentOffset().get(0).getBegin()); assertEquals( recognitionResults .getAudioMetrics() .getAccumulated() .getDirectCurrentOffset() .get(0) .getEnd(), result.getAudioMetrics().getAccumulated().getDirectCurrentOffset().get(0).getEnd()); assertEquals( recognitionResults .getAudioMetrics() .getAccumulated() .getDirectCurrentOffset() .get(0) .getCount(), result.getAudioMetrics().getAccumulated().getDirectCurrentOffset().get(0).getCount()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getClippingRate().get(0).getBegin(), result.getAudioMetrics().getAccumulated().getClippingRate().get(0).getBegin()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getClippingRate().get(0).getEnd(), result.getAudioMetrics().getAccumulated().getClippingRate().get(0).getEnd()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getClippingRate().get(0).getCount(), result.getAudioMetrics().getAccumulated().getClippingRate().get(0).getCount()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getBegin(), result.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getBegin()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getEnd(), result.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getEnd()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getCount(), result.getAudioMetrics().getAccumulated().getSpeechLevel().get(0).getCount()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getBegin(), result.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getBegin()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getEnd(), result.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getEnd()); assertEquals( recognitionResults.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getCount(), result.getAudioMetrics().getAccumulated().getNonSpeechLevel().get(0).getCount()); assertEquals( SpeechRecognitionResult.EndOfUtterance.END_OF_DATA, recognitionResults.getResults().get(0).getEndOfUtterance()); } /** * Test recognize WebM for WebM audio format. * * @throws URISyntaxException the URI syntax exception * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testRecognizeWebM() throws URISyntaxException, InterruptedException, FileNotFoundException { server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(recognitionResults))); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WEBM) .contentType(HttpMediaType.AUDIO_WEBM) .build(); final SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertNotNull(result); assertEquals(result, recognitionResults); assertEquals("POST", request.getMethod()); assertEquals(PATH_RECOGNIZE, request.getPath()); assertEquals(HttpMediaType.AUDIO_WEBM, request.getHeader(CONTENT_TYPE)); } /** * Test diarization. * * @throws URISyntaxException the URI syntax exception * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testRecognizeWithSpeakerLabels() throws URISyntaxException, InterruptedException, FileNotFoundException { FileInputStream jsonFile = new FileInputStream("src/test/resources/speech_to_text/diarization.json"); String diarizationStr = getStringFromInputStream(jsonFile); JsonObject diarization = new JsonParser().parse(diarizationStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(diarizationStr)); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .speakerLabels(true) .build(); SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(PATH_RECOGNIZE + "?speaker_labels=true", request.getPath()); assertEquals(diarization.toString(), GSON.toJsonTree(result).toString()); } /** * Test recognize with customization. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testRecognizeWithCustomization() throws FileNotFoundException, InterruptedException { String id = "foo"; String version = "version"; String recString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/recognition.json")); JsonObject recognition = new JsonParser().parse(recString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(recString)); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .languageCustomizationId(id) .baseModelVersion(version) .build(); SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( PATH_RECOGNIZE + "?language_customization_id=" + id + "&base_model_version=" + version, request.getPath()); assertEquals(recognition, GSON.toJsonTree(result)); } /** * Test recognize with acoustic customization. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testRecognizeWithAcousticCustomization() throws FileNotFoundException, InterruptedException { String id = "foo"; String version = "version"; String recString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/recognition.json")); JsonObject recognition = new JsonParser().parse(recString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(recString)); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .acousticCustomizationId(id) .baseModelVersion(version) .build(); SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( PATH_RECOGNIZE + "?acoustic_customization_id=" + id + "&base_model_version=" + version, request.getPath()); assertEquals(recognition, GSON.toJsonTree(result)); } /** * Test recognize with customization weight. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testRecognizeWithCustomizationWeight() throws FileNotFoundException, InterruptedException { String id = "foo"; String recString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/recognition.json")); JsonObject recognition = new JsonParser().parse(recString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(recString)); RecognizeOptions recognizeOptions = new RecognizeOptions.Builder() .audio(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .languageCustomizationId(id) .customizationWeight(0.5) .build(); SpeechRecognitionResults result = service.recognize(recognizeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals( PATH_RECOGNIZE + "?language_customization_id=" + id + "&customization_weight=0.5", request.getPath()); assertEquals(recognition, GSON.toJsonTree(result)); } /** Test MediaTypeUtils class. */ @Test public void testMediaTypeUtils() { assertEquals( HttpMediaType.AUDIO_WAV, MediaTypeUtils.getMediaTypeFromFile(new File("test.wav"))); assertEquals( HttpMediaType.AUDIO_OGG, MediaTypeUtils.getMediaTypeFromFile(new File("test.OGG"))); assertNull(MediaTypeUtils.getMediaTypeFromFile(new File("invalid.png"))); assertNull(MediaTypeUtils.getMediaTypeFromFile(new File("invalidwav"))); assertNull(MediaTypeUtils.getMediaTypeFromFile(null)); assertTrue(MediaTypeUtils.isValidMediaType("audio/wav")); assertFalse(MediaTypeUtils.isValidMediaType("image/png")); assertFalse(MediaTypeUtils.isValidMediaType(null)); } /** * Test create job. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testCreateJob() throws InterruptedException, FileNotFoundException { String callbackUrl = "callback"; String events = CreateJobOptions.Events.RECOGNITIONS_STARTED; String userToken = "token"; Long resultsTtl = 5L; File audio = SAMPLE_WAV; String contentType = HttpMediaType.AUDIO_WAV; String model = CreateJobOptions.Model.EN_US_BROADBANDMODEL; String customizationId = "customizationId"; Double customizationWeight = 5d; String version = "version"; Long inactivityTimeout = 20L; List<String> keywords = Arrays.asList("keyword1", "keyword2"); Float keywordsThreshold = 5f; Boolean wordConfidence = true; Boolean timestamps = true; Boolean profanityFilter = true; Boolean smartFormatting = true; Boolean speakerLabels = true; Double endOfPhraseSilenceTime = 2.0; Boolean splitTranscriptAtPhraseEnd = true; RecognitionJob job = loadFixture("src/test/resources/speech_to_text/job.json", RecognitionJob.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(job))); CreateJobOptions createOptions = new CreateJobOptions.Builder() .callbackUrl(callbackUrl) .events(events) .userToken(userToken) .resultsTtl(resultsTtl) .audio(audio) .contentType(contentType) .model(model) .languageCustomizationId(customizationId) .customizationWeight(customizationWeight) .baseModelVersion(version) .inactivityTimeout(inactivityTimeout) .keywords(keywords) .keywordsThreshold(keywordsThreshold) .wordConfidence(wordConfidence) .timestamps(timestamps) .profanityFilter(profanityFilter) .smartFormatting(smartFormatting) .speakerLabels(speakerLabels) .endOfPhraseSilenceTime(endOfPhraseSilenceTime) .splitTranscriptAtPhraseEnd(splitTranscriptAtPhraseEnd) .build(); assertEquals((Double) 2.0, createOptions.endOfPhraseSilenceTime()); assertTrue(createOptions.splitTranscriptAtPhraseEnd()); service.createJob(createOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( PATH_RECOGNITIONS + "?model=" + model + "&callback_url=" + callbackUrl + "&events=" + events + "&user_token=" + userToken + "&results_ttl=" + resultsTtl + "&language_customization_id=" + customizationId + "&base_model_version=" + version + "&customization_weight=" + customizationWeight + "&inactivity_timeout=" + inactivityTimeout + "&keywords=" + RequestUtils.encode(StringUtils.join(keywords, ',')) + "&keywords_threshold=" + keywordsThreshold + "&word_confidence=" + wordConfidence + "×tamps=" + timestamps + "&profanity_filter=" + profanityFilter + "&smart_formatting=" + smartFormatting + "&speaker_labels=" + speakerLabels + "&end_of_phrase_silence_time=" + endOfPhraseSilenceTime + "&split_transcript_at_phrase_end=" + splitTranscriptAtPhraseEnd, request.getPath()); } /** * Test delete job. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteJob() throws InterruptedException { String id = "foo"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteJobOptions deleteOptions = new DeleteJobOptions.Builder().id(id).build(); service.deleteJob(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_RECOGNITION, id), request.getPath()); } /** * Test check job. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testCheckJob() throws InterruptedException, FileNotFoundException { String id = "foo"; RecognitionJob job = loadFixture("src/test/resources/speech_to_text/job.json", RecognitionJob.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(job))); CheckJobOptions checkOptions = new CheckJobOptions.Builder().id(id).build(); RecognitionJob result = service.checkJob(checkOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_RECOGNITION, id), request.getPath()); assertEquals(result.toString(), job.toString()); } /** * Test check jobs. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testCheckJobs() throws InterruptedException, FileNotFoundException { String jobsAsString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/jobs.json")); JsonObject jobsAsJson = new JsonParser().parse(jobsAsString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(jobsAsString)); RecognitionJobs result = service.checkJobs().execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(PATH_RECOGNITIONS, request.getPath()); assertEquals(jobsAsJson.get("recognitions"), GSON.toJsonTree(result.getRecognitions())); } /** * Test list language models. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListLanguageModels() throws InterruptedException, FileNotFoundException { String customizationsAsString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/customizations.json")); JsonObject customizations = new JsonParser().parse(customizationsAsString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(customizationsAsString)); ListLanguageModelsOptions listOptions = new ListLanguageModelsOptions.Builder().language("en-us").build(); LanguageModels result = service.listLanguageModels(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(PATH_CUSTOMIZATIONS + "?language=en-us", request.getPath()); assertEquals( customizations.get("customizations").getAsJsonArray().size(), result.getCustomizations().size()); assertEquals(customizations.get("customizations"), GSON.toJsonTree(result.getCustomizations())); } /** * Test get language model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testGetLanguageModel() throws InterruptedException, FileNotFoundException { String id = "foo"; LanguageModel model = loadFixture("src/test/resources/speech_to_text/customization.json", LanguageModel.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(model))); GetLanguageModelOptions getOptions = new GetLanguageModelOptions.Builder().customizationId(id).build(); LanguageModel result = service.getLanguageModel(getOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_CUSTOMIZATION, id), request.getPath()); assertEquals(result.toString(), model.toString()); assertEquals(UPDATED, result.getUpdated()); } /** * Test create language model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testCreateLanguageModel() throws InterruptedException, FileNotFoundException { LanguageModel model = loadFixture("src/test/resources/speech_to_text/customization.json", LanguageModel.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(model))); CreateLanguageModelOptions createOptions = new CreateLanguageModelOptions.Builder() .name(model.getName()) .baseModelName("en-GB_BroadbandModel") .description(model.getDescription()) .build(); LanguageModel result = service.createLanguageModel(createOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(PATH_CUSTOMIZATIONS, request.getPath()); assertEquals(result.toString(), model.toString()); } /** * Test delete language model. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteLanguageModel() throws InterruptedException { String id = "foo"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteLanguageModelOptions deleteOptions = new DeleteLanguageModelOptions.Builder().customizationId(id).build(); service.deleteLanguageModel(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_CUSTOMIZATION, id), request.getPath()); } /** * Test train language model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testTrainLanguageModel() throws InterruptedException, FileNotFoundException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; TrainLanguageModelOptions trainOptions = new TrainLanguageModelOptions.Builder() .customizationId(id) .wordTypeToAdd(TrainLanguageModelOptions.WordTypeToAdd.ALL) .customizationWeight(0.5) .build(); service.trainLanguageModel(trainOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( String.format(PATH_TRAIN, id) + "?word_type_to_add=all&customization_weight=" + 0.5, request.getPath()); } /** * Test reset language model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testResetLanguageModel() throws InterruptedException, FileNotFoundException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; ResetLanguageModelOptions resetOptions = new ResetLanguageModelOptions.Builder().customizationId(id).build(); service.resetLanguageModel(resetOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(String.format(PATH_RESET, id), request.getPath()); } /** * Test upgrade language model. * * @throws InterruptedException the interrupted exception */ @Test public void testUpgradeLanguageModel() throws InterruptedException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; UpgradeLanguageModelOptions upgradeOptions = new UpgradeLanguageModelOptions.Builder().customizationId(id).build(); service.upgradeLanguageModel(upgradeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(String.format(PATH_UPGRADE, id), request.getPath()); } /** * Test list corpora. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListCorpora() throws InterruptedException, FileNotFoundException { String id = "foo"; String corporaAsString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/corpora.json")); JsonObject corpora = new JsonParser().parse(corporaAsString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(corporaAsString)); ListCorporaOptions listOptions = new ListCorporaOptions.Builder().customizationId(id).build(); Corpora result = service.listCorpora(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_CORPORA, id), request.getPath()); assertEquals(corpora.get("corpora"), GSON.toJsonTree(result.getCorpora())); } /** * Test get corpus. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testGetCorpus() throws InterruptedException, FileNotFoundException { String id = "foo"; String corpus = "cName"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); GetCorpusOptions getOptions = new GetCorpusOptions.Builder().customizationId(id).corpusName(corpus).build(); service.getCorpus(getOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_CORPUS, id, corpus), request.getPath()); } /** * Test delete corpus. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testDeleteCorpus() throws InterruptedException, FileNotFoundException { String id = "foo"; String corpus = "cName"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteCorpusOptions deleteOptions = new DeleteCorpusOptions.Builder().customizationId(id).corpusName(corpus).build(); service.deleteCorpus(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_CORPUS, id, corpus), request.getPath()); } /** * Test add corpus. * * @throws InterruptedException the interrupted exception * @throws IOException the IO exception */ @Test public void testAddCorpus() throws InterruptedException, IOException { String id = "foo"; String corpusName = "cName"; File corpusFile = new File("src/test/resources/speech_to_text/corpus-text.txt"); String corpusFileText = new String(Files.readAllBytes(Paths.get(corpusFile.toURI()))); server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); AddCorpusOptions addOptions = new AddCorpusOptions.Builder() .customizationId(id) .corpusName(corpusName) .corpusFile(corpusFile) .allowOverwrite(true) .build(); service.addCorpus(addOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( String.format(PATH_CORPUS, id, corpusName) + "?allow_overwrite=true", request.getPath()); assertTrue(request.getBody().readUtf8().contains(corpusFileText)); } /** * Test list words. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListWords() throws InterruptedException, FileNotFoundException { String id = "foo"; String wordsAsStr = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/words.json")); JsonObject words = new JsonParser().parse(wordsAsStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(wordsAsStr)); ListWordsOptions listOptions = new ListWordsOptions.Builder().customizationId(id).build(); Words result = service.listWords(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_WORDS, id), request.getPath()); assertEquals(words.get("words"), GSON.toJsonTree(result.getWords())); } /** * Test list words with word type all. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListWordsType() throws InterruptedException, FileNotFoundException { String id = "foo"; String wordsAsStr = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/words.json")); JsonObject words = new JsonParser().parse(wordsAsStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(wordsAsStr)); ListWordsOptions listOptions = new ListWordsOptions.Builder() .customizationId(id) .wordType(ListWordsOptions.WordType.ALL) .build(); Words result = service.listWords(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_WORDS, id) + "?word_type=all", request.getPath()); assertEquals(words.get("words"), GSON.toJsonTree(result.getWords())); } /** * Test list words with sort order alphabetical. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListWordsSort() throws InterruptedException, FileNotFoundException { String id = "foo"; String wordsAsStr = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/words.json")); JsonObject words = new JsonParser().parse(wordsAsStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(wordsAsStr)); ListWordsOptions listOptions = new ListWordsOptions.Builder() .customizationId(id) .sort(ListWordsOptions.Sort.ALPHABETICAL) .build(); Words result = service.listWords(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_WORDS, id) + "?sort=alphabetical", request.getPath()); assertEquals(words.get("words"), GSON.toJsonTree(result.getWords())); } /** * Test list words with word type all and sort order alphabetical. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListWordsTypeSort() throws InterruptedException, FileNotFoundException { String id = "foo"; String wordsAsStr = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/words.json")); JsonObject words = new JsonParser().parse(wordsAsStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(wordsAsStr)); ListWordsOptions listOptions = new ListWordsOptions.Builder() .customizationId(id) .sort(ListWordsOptions.Sort.ALPHABETICAL) .wordType(ListWordsOptions.WordType.ALL) .build(); Words result = service.listWords(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals( String.format(PATH_WORDS, id) + "?word_type=all&sort=alphabetical", request.getPath()); assertEquals(words.get("words"), GSON.toJsonTree(result.getWords())); } /** * Test get word. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testGetWord() throws InterruptedException, FileNotFoundException { String id = "foo"; String wordName = "bar"; String wordAsStr = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/word.json")); JsonObject word = new JsonParser().parse(wordAsStr).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(wordAsStr)); GetWordOptions getOptions = new GetWordOptions.Builder().customizationId(id).wordName(wordName).build(); Word result = service.getWord(getOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_WORD, id, wordName), request.getPath()); assertEquals(word, GSON.toJsonTree(result)); } /** * Test delete word. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteWord() throws InterruptedException { String id = "foo"; String wordName = "bar"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteWordOptions deleteOptions = new DeleteWordOptions.Builder().customizationId(id).wordName(wordName).build(); service.deleteWord(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_WORD, id, wordName), request.getPath()); } /** * Test add words. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testAddWords() throws InterruptedException, FileNotFoundException { String id = "foo"; Word newWord = loadFixture("src/test/resources/speech_to_text/word.json", Word.class); Map<String, Object> wordsAsMap = new HashMap<String, Object>(); wordsAsMap.put("words", new Word[] {newWord}); server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); CustomWord word = new CustomWord.Builder() .word(newWord.getWord()) .displayAs(newWord.getDisplayAs()) .soundsLike(newWord.getSoundsLike()) .build(); AddWordsOptions addOptions = new AddWordsOptions.Builder().customizationId(id).addWords(word).build(); service.addWords(addOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(String.format(PATH_WORDS, id), request.getPath()); Gson testGsonNoNulls = new Gson(); assertEquals(testGsonNoNulls.toJson(wordsAsMap), request.getBody().readUtf8()); } /** * Test add word. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testAddWord() throws InterruptedException, FileNotFoundException { String id = "foo"; Word newWord = loadFixture("src/test/resources/speech_to_text/word.json", Word.class); server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); AddWordOptions addOptions = new AddWordOptions.Builder() .wordName(newWord.getWord()) .customizationId(id) .word(newWord.getWord()) .displayAs(newWord.getDisplayAs()) .soundsLike(newWord.getSoundsLike()) .build(); service.addWord(addOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("PUT", request.getMethod()); assertEquals(String.format(PATH_WORD, id, newWord.getWord()), request.getPath()); Gson testGsonNoNulls = new Gson(); assertEquals(testGsonNoNulls.toJson(newWord), request.getBody().readUtf8()); } /** * Test create acoustic model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testCreateAcousticModel() throws InterruptedException, FileNotFoundException { AcousticModel model = loadFixture("src/test/resources/speech_to_text/acoustic-model.json", AcousticModel.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(model))); CreateAcousticModelOptions createOptions = new CreateAcousticModelOptions.Builder() .name(model.getName()) .baseModelName(model.getBaseModelName()) .description(model.getDescription()) .build(); AcousticModel result = service.createAcousticModel(createOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(PATH_ACOUSTIC_CUSTOMIZATIONS, request.getPath()); assertEquals(result.toString(), model.toString()); } /** * Test list acoustic models. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testListAcousticModels() throws InterruptedException, FileNotFoundException { String acousticModelsAsString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/acoustic-models.json")); JsonObject acousticModels = new JsonParser().parse(acousticModelsAsString).getAsJsonObject(); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(acousticModelsAsString)); ListAcousticModelsOptions listOptions = new ListAcousticModelsOptions.Builder().language("en-us").build(); AcousticModels result = service.listAcousticModels(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(PATH_ACOUSTIC_CUSTOMIZATIONS + "?language=en-us", request.getPath()); assertEquals( acousticModels.get("customizations").getAsJsonArray().size(), result.getCustomizations().size()); assertEquals(acousticModels.get("customizations"), GSON.toJsonTree(result.getCustomizations())); } /** * Test get acoustic model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testGetAcousticModel() throws InterruptedException, FileNotFoundException { String id = "foo"; AcousticModel model = loadFixture("src/test/resources/speech_to_text/acoustic-model.json", AcousticModel.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(model))); GetAcousticModelOptions getOptions = new GetAcousticModelOptions.Builder().customizationId(id).build(); AcousticModel result = service.getAcousticModel(getOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_ACOUSTIC_CUSTOMIZATION, id), request.getPath()); assertEquals(result.toString(), model.toString()); assertEquals(UPDATED, result.getUpdated()); } /** * Test delete acoustic model. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteAcousticModel() throws InterruptedException { String id = "foo"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteAcousticModelOptions deleteOptions = new DeleteAcousticModelOptions.Builder().customizationId(id).build(); service.deleteAcousticModel(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_ACOUSTIC_CUSTOMIZATION, id), request.getPath()); } /** * Test train acoustic model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testTrainAcousticModel() throws InterruptedException, FileNotFoundException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; String languageModelId = "bar"; TrainAcousticModelOptions trainOptions = new TrainAcousticModelOptions.Builder() .customizationId(id) .customLanguageModelId(languageModelId) .build(); service.trainAcousticModel(trainOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( String.format(PATH_ACOUSTIC_TRAIN, id) + "?custom_language_model_id=bar", request.getPath()); } /** * Test reset acoustic model. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testResetAcousticModel() throws InterruptedException, FileNotFoundException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; ResetAcousticModelOptions resetOptions = new ResetAcousticModelOptions.Builder().customizationId(id).build(); service.resetAcousticModel(resetOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals(String.format(PATH_ACOUSTIC_RESET, id), request.getPath()); } /** * Test upgrade acoustic model. * * @throws InterruptedException the interrupted exception */ @Test public void testUpgradeAcousticModel() throws InterruptedException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; String languageModelId = "modelId"; UpgradeAcousticModelOptions upgradeOptions = new UpgradeAcousticModelOptions.Builder() .customizationId(id) .customLanguageModelId(languageModelId) .force(true) .build(); upgradeOptions = upgradeOptions.newBuilder().build(); service.upgradeAcousticModel(upgradeOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( String.format(PATH_ACOUSTIC_UPGRADE, id) + "?custom_language_model_id=" + languageModelId + "&force=true", request.getPath()); } /** * Test add audio. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testAddAudio() throws InterruptedException, FileNotFoundException { server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); String id = "foo"; String audioName = "test_file"; AddAudioOptions addOptions = new AddAudioOptions.Builder() .customizationId(id) .audioResource(SAMPLE_WAV) .contentType(HttpMediaType.AUDIO_WAV) .audioName(audioName) .allowOverwrite(true) .build(); service.addAudio(addOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("POST", request.getMethod()); assertEquals( String.format(PATH_SPECIFIC_AUDIO, id, audioName) + "?allow_overwrite=true", request.getPath()); } /** * Test list audio. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testListAudio() throws FileNotFoundException, InterruptedException { String resourcesAsString = getStringFromInputStream( new FileInputStream("src/test/resources/speech_to_text/audio-resources.json")); JsonObject audioResources = new JsonParser().parse(resourcesAsString).getAsJsonObject(); String id = "foo"; server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(resourcesAsString)); ListAudioOptions listOptions = new ListAudioOptions.Builder().customizationId(id).build(); AudioResources result = service.listAudio(listOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_ALL_AUDIO, id), request.getPath()); assertEquals(audioResources.get("audio").getAsJsonArray().size(), result.getAudio().size()); assertEquals(audioResources.get("audio"), GSON.toJsonTree(result.getAudio())); } /** * Test get audio. * * @throws InterruptedException the interrupted exception * @throws FileNotFoundException the file not found exception */ @Test public void testGetAudio() throws InterruptedException, FileNotFoundException { String id = "foo"; String audioName = "audio1"; AudioResource audio = loadFixture("src/test/resources/speech_to_text/audio-resource.json", AudioResource.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(audio))); GetAudioOptions getOptions = new GetAudioOptions.Builder().customizationId(id).audioName(audioName).build(); AudioListing result = service.getAudio(getOptions).execute().getResult(); final RecordedRequest request = server.takeRequest(); assertEquals("GET", request.getMethod()); assertEquals(String.format(PATH_SPECIFIC_AUDIO, id, audioName), request.getPath()); assertEquals(audio.getDetails(), result.getDetails()); assertEquals(audio.getDuration(), result.getDuration()); assertEquals(audio.getName(), result.getName()); assertEquals(audio.getStatus(), result.getStatus()); } /** * Test delete audio. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteAudio() throws InterruptedException { String id = "foo"; String audioName = "audio1"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); DeleteAudioOptions deleteOptions = new DeleteAudioOptions.Builder().customizationId(id).audioName(audioName).build(); service.deleteAudio(deleteOptions).execute(); final RecordedRequest request = server.takeRequest(); assertEquals("DELETE", request.getMethod()); assertEquals(String.format(PATH_SPECIFIC_AUDIO, id, audioName), request.getPath()); } /** * Test register callback. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testRegisterCallback() throws FileNotFoundException, InterruptedException { String callbackUrl = "http://testurl.com"; String secret = "secret"; RegisterStatus registerStatus = loadFixture("src/test/resources/speech_to_text/register-status.json", RegisterStatus.class); server.enqueue( new MockResponse() .addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON) .setBody(GSON.toJson(registerStatus))); RegisterCallbackOptions registerOptions = new RegisterCallbackOptions.Builder().callbackUrl(callbackUrl).userSecret(secret).build(); RegisterStatus result = service.registerCallback(registerOptions).execute().getResult(); final RecordedRequest registerRequest = server.takeRequest(); assertEquals("POST", registerRequest.getMethod()); assertEquals( String.format( REGISTER_CALLBACK, RequestUtils.encode(callbackUrl), RequestUtils.encode(secret)), registerRequest.getPath()); assertEquals(RegisterStatus.Status.CREATED, result.getStatus()); assertEquals(callbackUrl, result.getUrl()); } /** * Test unregister callback. * * @throws InterruptedException the interrupted exception */ @Test public void testUnregisterCallback() throws InterruptedException { String callbackUrl = "http://testurl.com"; server.enqueue( new MockResponse().addHeader(CONTENT_TYPE, HttpMediaType.APPLICATION_JSON).setBody("{}")); UnregisterCallbackOptions unregisterOptions = new UnregisterCallbackOptions.Builder().callbackUrl(callbackUrl).build(); service.unregisterCallback(unregisterOptions).execute().getResult(); final RecordedRequest unregisterRequest = server.takeRequest(); assertEquals("POST", unregisterRequest.getMethod()); assertEquals( String.format(UNREGISTER_CALLBACK, RequestUtils.encode(callbackUrl)), unregisterRequest.getPath()); } /** * Test closing input stream closes web socket. * * @throws Exception the exception */ @Test public void testClosingInputStreamClosesWebSocket() throws Exception { TestRecognizeCallback callback = new TestRecognizeCallback(); WebSocketRecorder webSocketRecorder = new WebSocketRecorder("server"); PipedOutputStream outputStream = new PipedOutputStream(); InputStream inputStream = new PipedInputStream(outputStream); server.enqueue(new MockResponse().withWebSocketUpgrade(webSocketRecorder)); String customizationId = "id"; String version = "version"; Double customizationWeight = 0.1; RecognizeOptions options = new RecognizeOptions.Builder() .audio(inputStream) .contentType(HttpMediaType.createAudioRaw(44000)) .customizationId(customizationId) .baseModelVersion(version) .customizationWeight(customizationWeight) .build(); service.recognizeUsingWebSocket(options, callback); WebSocket serverSocket = webSocketRecorder.assertOpen(); serverSocket.send("{\"state\": {}}"); outputStream.write(ByteString.encodeUtf8("test").toByteArray()); outputStream.close(); webSocketRecorder.assertTextMessage( "{\"content-type\":\"audio/l16; rate=44000\"," + "\"customization_weight\":0.1,\"action\":\"start\"}"); webSocketRecorder.assertBinaryMessage(ByteString.encodeUtf8("test")); webSocketRecorder.assertTextMessage("{\"action\":\"stop\"}"); webSocketRecorder.assertExhausted(); serverSocket.close(1000, null); callback.assertConnected(); callback.assertDisconnected(); callback.assertNoErrors(); callback.assertOnTranscriptionComplete(); } /** * Test add grammar. * * @throws FileNotFoundException the file not found exception * @throws InterruptedException the interrupted exception */ @Test public void testAddGrammar() throws FileNotFoundException, InterruptedException { MockResponse desiredResponse = new MockResponse().setResponseCode(200); server.enqueue(desiredResponse); String customizationId = "id"; String grammarName = "grammar_name"; InputStream grammarFile = new FileInputStream(SAMPLE_WAV); AddGrammarOptions addGrammarOptions = new AddGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .grammarFile(grammarFile) .contentType("application/srgs") .build(); service.addGrammar(addGrammarOptions).execute().getResult(); RecordedRequest request = server.takeRequest(); assertEquals(POST, request.getMethod()); } /** * Test list grammars. * * @throws InterruptedException the interrupted exception */ @Test public void testListGrammars() throws InterruptedException { server.enqueue(jsonResponse(grammars)); String customizationId = "id"; ListGrammarsOptions listGrammarsOptions = new ListGrammarsOptions.Builder().customizationId(customizationId).build(); Grammars response = service.listGrammars(listGrammarsOptions).execute().getResult(); RecordedRequest request = server.takeRequest(); assertEquals(GET, request.getMethod()); assertEquals(grammars, response); } /** * Test get grammar. * * @throws InterruptedException the interrupted exception */ @Test public void testGetGrammar() throws InterruptedException { server.enqueue(jsonResponse(grammar)); String customizationId = "id"; String grammarName = "grammar_name"; GetGrammarOptions getGrammarOptions = new GetGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .build(); Grammar response = service.getGrammar(getGrammarOptions).execute().getResult(); RecordedRequest request = server.takeRequest(); assertEquals(GET, request.getMethod()); assertEquals(grammar, response); } /** * Test delete grammar. * * @throws InterruptedException the interrupted exception */ @Test public void testDeleteGrammar() throws InterruptedException { MockResponse desiredResponse = new MockResponse().setResponseCode(200); server.enqueue(desiredResponse); String customizationId = "id"; String grammarName = "grammar_name"; DeleteGrammarOptions deleteGrammarOptions = new DeleteGrammarOptions.Builder() .customizationId(customizationId) .grammarName(grammarName) .build(); service.deleteGrammar(deleteGrammarOptions).execute(); RecordedRequest request = server.takeRequest(); assertEquals(DELETE, request.getMethod()); } // --- HELPERS --- private static class TestRecognizeCallback implements RecognizeCallback { private final BlockingQueue<SpeechRecognitionResults> speechResults = new LinkedBlockingQueue<>(); private final BlockingQueue<Exception> errors = new LinkedBlockingQueue<>(); private final BlockingQueue<Object> onDisconnectedCalls = new LinkedBlockingQueue<>(); private final BlockingQueue<Object> onConnectedCalls = new LinkedBlockingQueue<>(); private final BlockingQueue<Object> onTranscriptionCompleteCalls = new LinkedBlockingQueue<>(); @Override public void onTranscription(SpeechRecognitionResults speechResults) { this.speechResults.add(speechResults); } @Override public void onConnected() { this.onConnectedCalls.add(new Object()); } @Override public void onError(Exception e) { this.errors.add(e); } @Override public void onDisconnected() { this.onDisconnectedCalls.add(new Object()); } private void assertOnTranscriptionComplete() { if (this.onTranscriptionCompleteCalls.size() == 1) { throw new AssertionError( "There were " + this.errors.size() + " calls to onTranscriptionComplete"); } } private void assertConnected() { try { Object connectedEvent = this.onConnectedCalls.poll(10, TimeUnit.SECONDS); if (connectedEvent == null) { throw new AssertionError("Timed out waiting for connect."); } } catch (InterruptedException e) { throw new AssertionError(e); } } private void assertDisconnected() { try { Object disconnectedEvent = this.onDisconnectedCalls.poll(10, TimeUnit.SECONDS); if (disconnectedEvent == null) { throw new AssertionError("Timed out waiting for disconnect."); } } catch (InterruptedException e) { throw new AssertionError(e); } } private void assertNoErrors() { if (this.errors.size() > 0) { throw new AssertionError("There were " + this.errors.size() + " errors"); } } @Override public void onInactivityTimeout(RuntimeException runtimeException) {} @Override public void onListening() {} @Override public void onTranscriptionComplete() { this.onTranscriptionCompleteCalls.add(new Object()); } } }