blob: 270b3e2772495f9290d1aa5882f29770be730635 [file] [log] [blame]
henrike@webrtc.org28e20752013-07-10 00:45:36 +00001/*
kjellanderb24317b2016-02-10 07:54:43 -08002 * Copyright 2012 The WebRTC project authors. All Rights Reserved.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00003 *
kjellanderb24317b2016-02-10 07:54:43 -08004 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
henrike@webrtc.org28e20752013-07-10 00:45:36 +00009 */
10
Steve Anton10542f22019-01-11 09:11:00 -080011#include "pc/dtmf_sender.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000012
Yves Gerey3e707812018-11-28 16:47:49 +010013#include <stddef.h>
Jonas Olssona4d87372019-07-05 19:08:33 +020014
kwibergd1fe2812016-04-27 06:47:29 -070015#include <memory>
henrike@webrtc.org28e20752013-07-10 00:45:36 +000016#include <string>
17#include <vector>
18
Steve Anton10542f22019-01-11 09:11:00 -080019#include "rtc_base/fake_clock.h"
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020020#include "rtc_base/gunit.h"
Steve Anton10542f22019-01-11 09:11:00 -080021#include "rtc_base/time_utils.h"
Yves Gerey3e707812018-11-28 16:47:49 +010022#include "test/gtest.h"
henrike@webrtc.org28e20752013-07-10 00:45:36 +000023
henrike@webrtc.org28e20752013-07-10 00:45:36 +000024using webrtc::DtmfProviderInterface;
25using webrtc::DtmfSender;
26using webrtc::DtmfSenderObserverInterface;
27
deadbeefe7fc7d52016-10-28 13:53:08 -070028// TODO(deadbeef): Even though this test now uses a fake clock, it has a
29// generous 3-second timeout for every test case. The timeout could be tuned
30// to each test based on the tones sent, instead.
henrike@webrtc.org28e20752013-07-10 00:45:36 +000031static const int kMaxWaitMs = 3000;
32
Magnus Jedvertfc950842015-10-12 16:10:43 +020033class FakeDtmfObserver : public DtmfSenderObserverInterface {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000034 public:
35 FakeDtmfObserver() : completed_(false) {}
36
37 // Implements DtmfSenderObserverInterface.
kjellander@webrtc.org14665ff2015-03-04 12:58:35 +000038 void OnToneChange(const std::string& tone) override {
Harald Alvestrandd7b79af2018-09-06 09:33:56 +020039 tones_from_single_argument_callback_.push_back(tone);
40 if (tone.empty()) {
41 completed_ = true;
42 }
43 }
44 void OnToneChange(const std::string& tone,
45 const std::string& tone_buffer) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000046 tones_.push_back(tone);
Harald Alvestrandd7b79af2018-09-06 09:33:56 +020047 tones_remaining_ = tone_buffer;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000048 if (tone.empty()) {
49 completed_ = true;
50 }
51 }
52
53 // getters
Yves Gerey665174f2018-06-19 15:03:05 +020054 const std::vector<std::string>& tones() const { return tones_; }
Harald Alvestrandd7b79af2018-09-06 09:33:56 +020055 const std::vector<std::string>& tones_from_single_argument_callback() const {
56 return tones_from_single_argument_callback_;
57 }
58 const std::string tones_remaining() { return tones_remaining_; }
Yves Gerey665174f2018-06-19 15:03:05 +020059 bool completed() const { return completed_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000060
61 private:
62 std::vector<std::string> tones_;
Harald Alvestrandd7b79af2018-09-06 09:33:56 +020063 std::vector<std::string> tones_from_single_argument_callback_;
64 std::string tones_remaining_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +000065 bool completed_;
66};
67
68class FakeDtmfProvider : public DtmfProviderInterface {
69 public:
70 struct DtmfInfo {
71 DtmfInfo(int code, int duration, int gap)
Yves Gerey665174f2018-06-19 15:03:05 +020072 : code(code), duration(duration), gap(gap) {}
henrike@webrtc.org28e20752013-07-10 00:45:36 +000073 int code;
74 int duration;
75 int gap;
76 };
77
78 FakeDtmfProvider() : last_insert_dtmf_call_(0) {}
79
Yves Gerey665174f2018-06-19 15:03:05 +020080 ~FakeDtmfProvider() { SignalDestroyed(); }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000081
82 // Implements DtmfProviderInterface.
deadbeef20cb0c12017-02-01 20:27:00 -080083 bool CanInsertDtmf() override { return can_insert_; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +000084
deadbeef20cb0c12017-02-01 20:27:00 -080085 bool InsertDtmf(int code, int duration) override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000086 int gap = 0;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +000087 // TODO(ronghuawu): Make the timer (basically the rtc::TimeNanos)
henrike@webrtc.org28e20752013-07-10 00:45:36 +000088 // mockable and use a fake timer in the unit tests.
89 if (last_insert_dtmf_call_ > 0) {
Honghai Zhang82d78622016-05-06 11:29:15 -070090 gap = static_cast<int>(rtc::TimeMillis() - last_insert_dtmf_call_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +000091 }
Honghai Zhang82d78622016-05-06 11:29:15 -070092 last_insert_dtmf_call_ = rtc::TimeMillis();
henrike@webrtc.org28e20752013-07-10 00:45:36 +000093
henrike@webrtc.org28e20752013-07-10 00:45:36 +000094 dtmf_info_queue_.push_back(DtmfInfo(code, duration, gap));
95 return true;
96 }
97
nisseef8b61e2016-04-29 06:09:15 -070098 sigslot::signal0<>* GetOnDestroyedSignal() override {
henrike@webrtc.org28e20752013-07-10 00:45:36 +000099 return &SignalDestroyed;
100 }
101
102 // getter and setter
103 const std::vector<DtmfInfo>& dtmf_info_queue() const {
104 return dtmf_info_queue_;
105 }
106
107 // helper functions
deadbeef20cb0c12017-02-01 20:27:00 -0800108 void SetCanInsertDtmf(bool can_insert) { can_insert_ = can_insert; }
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000109
110 private:
deadbeef20cb0c12017-02-01 20:27:00 -0800111 bool can_insert_ = false;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000112 std::vector<DtmfInfo> dtmf_info_queue_;
Peter Boström0c4e06b2015-10-07 12:23:21 +0200113 int64_t last_insert_dtmf_call_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000114 sigslot::signal0<> SignalDestroyed;
115};
116
Mirko Bonadei6a489f22019-04-09 15:11:12 +0200117class DtmfSenderTest : public ::testing::Test {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000118 protected:
119 DtmfSenderTest()
Tomas Gunnarssone249d192021-04-26 11:46:54 +0200120 : observer_(new FakeDtmfObserver()), provider_(new FakeDtmfProvider()) {
deadbeef20cb0c12017-02-01 20:27:00 -0800121 provider_->SetCanInsertDtmf(true);
Steve Antonb983bae2018-06-20 11:16:53 -0700122 dtmf_ = DtmfSender::Create(rtc::Thread::Current(), provider_.get());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000123 dtmf_->RegisterObserver(observer_.get());
124 }
125
126 ~DtmfSenderTest() {
127 if (dtmf_.get()) {
128 dtmf_->UnregisterObserver();
129 }
130 }
131
Artem Titov880fa812021-07-30 22:30:23 +0200132 // Constructs a list of DtmfInfo from `tones`, `duration` and
133 // `inter_tone_gap`.
Aaron Alaniz529d8862020-01-21 03:09:47 +0000134 void GetDtmfInfoFromString(
135 const std::string& tones,
136 int duration,
137 int inter_tone_gap,
138 std::vector<FakeDtmfProvider::DtmfInfo>* dtmfs,
139 int comma_delay = webrtc::DtmfSender::kDtmfDefaultCommaDelayMs) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000140 // Init extra_delay as -inter_tone_gap - duration to ensure the first
141 // DtmfInfo's gap field will be 0.
142 int extra_delay = -1 * (inter_tone_gap + duration);
143
144 std::string::const_iterator it = tones.begin();
145 for (; it != tones.end(); ++it) {
146 char tone = *it;
147 int code = 0;
148 webrtc::GetDtmfCode(tone, &code);
149 if (tone == ',') {
Aaron Alaniz529d8862020-01-21 03:09:47 +0000150 extra_delay = comma_delay;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000151 } else {
Yves Gerey665174f2018-06-19 15:03:05 +0200152 dtmfs->push_back(FakeDtmfProvider::DtmfInfo(
153 code, duration, duration + inter_tone_gap + extra_delay));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000154 extra_delay = 0;
155 }
156 }
157 }
158
Steve Antonb983bae2018-06-20 11:16:53 -0700159 void VerifyExpectedState(const std::string& tones,
Yves Gerey665174f2018-06-19 15:03:05 +0200160 int duration,
161 int inter_tone_gap) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000162 EXPECT_EQ(tones, dtmf_->tones());
163 EXPECT_EQ(duration, dtmf_->duration());
164 EXPECT_EQ(inter_tone_gap, dtmf_->inter_tone_gap());
165 }
166
167 // Verify the provider got all the expected calls.
Aaron Alaniz529d8862020-01-21 03:09:47 +0000168 void VerifyOnProvider(
169 const std::string& tones,
170 int duration,
171 int inter_tone_gap,
172 int comma_delay = webrtc::DtmfSender::kDtmfDefaultCommaDelayMs) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000173 std::vector<FakeDtmfProvider::DtmfInfo> dtmf_queue_ref;
Aaron Alaniz529d8862020-01-21 03:09:47 +0000174 GetDtmfInfoFromString(tones, duration, inter_tone_gap, &dtmf_queue_ref,
175 comma_delay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000176 VerifyOnProvider(dtmf_queue_ref);
177 }
178
179 void VerifyOnProvider(
180 const std::vector<FakeDtmfProvider::DtmfInfo>& dtmf_queue_ref) {
181 const std::vector<FakeDtmfProvider::DtmfInfo>& dtmf_queue =
182 provider_->dtmf_info_queue();
183 ASSERT_EQ(dtmf_queue_ref.size(), dtmf_queue.size());
184 std::vector<FakeDtmfProvider::DtmfInfo>::const_iterator it_ref =
185 dtmf_queue_ref.begin();
186 std::vector<FakeDtmfProvider::DtmfInfo>::const_iterator it =
187 dtmf_queue.begin();
188 while (it_ref != dtmf_queue_ref.end() && it != dtmf_queue.end()) {
189 EXPECT_EQ(it_ref->code, it->code);
190 EXPECT_EQ(it_ref->duration, it->duration);
deadbeefe7fc7d52016-10-28 13:53:08 -0700191 // Allow ~10ms error (can be small since we're using a fake clock).
192 EXPECT_GE(it_ref->gap, it->gap - 10);
193 EXPECT_LE(it_ref->gap, it->gap + 10);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000194 ++it_ref;
195 ++it;
196 }
197 }
198
199 // Verify the observer got all the expected callbacks.
200 void VerifyOnObserver(const std::string& tones_ref) {
201 const std::vector<std::string>& tones = observer_->tones();
202 // The observer will get an empty string at the end.
203 EXPECT_EQ(tones_ref.size() + 1, tones.size());
Harald Alvestrandd7b79af2018-09-06 09:33:56 +0200204 EXPECT_EQ(observer_->tones(),
205 observer_->tones_from_single_argument_callback());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000206 EXPECT_TRUE(tones.back().empty());
Harald Alvestrandd7b79af2018-09-06 09:33:56 +0200207 EXPECT_TRUE(observer_->tones_remaining().empty());
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000208 std::string::const_iterator it_ref = tones_ref.begin();
209 std::vector<std::string>::const_iterator it = tones.begin();
210 while (it_ref != tones_ref.end() && it != tones.end()) {
211 EXPECT_EQ(*it_ref, it->at(0));
212 ++it_ref;
213 ++it;
214 }
215 }
216
kwibergd1fe2812016-04-27 06:47:29 -0700217 std::unique_ptr<FakeDtmfObserver> observer_;
218 std::unique_ptr<FakeDtmfProvider> provider_;
buildbot@webrtc.orgd4e598d2014-07-29 17:36:52 +0000219 rtc::scoped_refptr<DtmfSender> dtmf_;
deadbeefe7fc7d52016-10-28 13:53:08 -0700220 rtc::ScopedFakeClock fake_clock_;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000221};
222
223TEST_F(DtmfSenderTest, CanInsertDtmf) {
224 EXPECT_TRUE(dtmf_->CanInsertDtmf());
deadbeef20cb0c12017-02-01 20:27:00 -0800225 provider_->SetCanInsertDtmf(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000226 EXPECT_FALSE(dtmf_->CanInsertDtmf());
227}
228
229TEST_F(DtmfSenderTest, InsertDtmf) {
230 std::string tones = "@1%a&*$";
231 int duration = 100;
232 int inter_tone_gap = 50;
233 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
deadbeefe7fc7d52016-10-28 13:53:08 -0700234 EXPECT_TRUE_SIMULATED_WAIT(observer_->completed(), kMaxWaitMs, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000235
236 // The unrecognized characters should be ignored.
237 std::string known_tones = "1a*";
238 VerifyOnProvider(known_tones, duration, inter_tone_gap);
239 VerifyOnObserver(known_tones);
240}
241
242TEST_F(DtmfSenderTest, InsertDtmfTwice) {
243 std::string tones1 = "12";
244 std::string tones2 = "ab";
245 int duration = 100;
246 int inter_tone_gap = 50;
247 EXPECT_TRUE(dtmf_->InsertDtmf(tones1, duration, inter_tone_gap));
Steve Antonb983bae2018-06-20 11:16:53 -0700248 VerifyExpectedState(tones1, duration, inter_tone_gap);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000249 // Wait until the first tone got sent.
deadbeefe7fc7d52016-10-28 13:53:08 -0700250 EXPECT_TRUE_SIMULATED_WAIT(observer_->tones().size() == 1, kMaxWaitMs,
251 fake_clock_);
Steve Antonb983bae2018-06-20 11:16:53 -0700252 VerifyExpectedState("2", duration, inter_tone_gap);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000253 // Insert with another tone buffer.
254 EXPECT_TRUE(dtmf_->InsertDtmf(tones2, duration, inter_tone_gap));
Steve Antonb983bae2018-06-20 11:16:53 -0700255 VerifyExpectedState(tones2, duration, inter_tone_gap);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000256 // Wait until it's completed.
deadbeefe7fc7d52016-10-28 13:53:08 -0700257 EXPECT_TRUE_SIMULATED_WAIT(observer_->completed(), kMaxWaitMs, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000258
259 std::vector<FakeDtmfProvider::DtmfInfo> dtmf_queue_ref;
260 GetDtmfInfoFromString("1", duration, inter_tone_gap, &dtmf_queue_ref);
261 GetDtmfInfoFromString("ab", duration, inter_tone_gap, &dtmf_queue_ref);
262 VerifyOnProvider(dtmf_queue_ref);
263 VerifyOnObserver("1ab");
264}
265
266TEST_F(DtmfSenderTest, InsertDtmfWhileProviderIsDeleted) {
267 std::string tones = "@1%a&*$";
268 int duration = 100;
269 int inter_tone_gap = 50;
270 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
271 // Wait until the first tone got sent.
deadbeefe7fc7d52016-10-28 13:53:08 -0700272 EXPECT_TRUE_SIMULATED_WAIT(observer_->tones().size() == 1, kMaxWaitMs,
273 fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000274 // Delete provider.
275 provider_.reset();
276 // The queue should be discontinued so no more tone callbacks.
deadbeefe7fc7d52016-10-28 13:53:08 -0700277 SIMULATED_WAIT(false, 200, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000278 EXPECT_EQ(1U, observer_->tones().size());
279}
280
281TEST_F(DtmfSenderTest, InsertDtmfWhileSenderIsDeleted) {
282 std::string tones = "@1%a&*$";
283 int duration = 100;
284 int inter_tone_gap = 50;
285 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
286 // Wait until the first tone got sent.
deadbeefe7fc7d52016-10-28 13:53:08 -0700287 EXPECT_TRUE_SIMULATED_WAIT(observer_->tones().size() == 1, kMaxWaitMs,
288 fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000289 // Delete the sender.
290 dtmf_ = NULL;
291 // The queue should be discontinued so no more tone callbacks.
deadbeefe7fc7d52016-10-28 13:53:08 -0700292 SIMULATED_WAIT(false, 200, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000293 EXPECT_EQ(1U, observer_->tones().size());
294}
295
296TEST_F(DtmfSenderTest, InsertEmptyTonesToCancelPreviousTask) {
297 std::string tones1 = "12";
298 std::string tones2 = "";
299 int duration = 100;
300 int inter_tone_gap = 50;
301 EXPECT_TRUE(dtmf_->InsertDtmf(tones1, duration, inter_tone_gap));
302 // Wait until the first tone got sent.
deadbeefe7fc7d52016-10-28 13:53:08 -0700303 EXPECT_TRUE_SIMULATED_WAIT(observer_->tones().size() == 1, kMaxWaitMs,
304 fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000305 // Insert with another tone buffer.
306 EXPECT_TRUE(dtmf_->InsertDtmf(tones2, duration, inter_tone_gap));
307 // Wait until it's completed.
deadbeefe7fc7d52016-10-28 13:53:08 -0700308 EXPECT_TRUE_SIMULATED_WAIT(observer_->completed(), kMaxWaitMs, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000309
310 std::vector<FakeDtmfProvider::DtmfInfo> dtmf_queue_ref;
311 GetDtmfInfoFromString("1", duration, inter_tone_gap, &dtmf_queue_ref);
312 VerifyOnProvider(dtmf_queue_ref);
313 VerifyOnObserver("1");
314}
315
Aaron Alaniz529d8862020-01-21 03:09:47 +0000316TEST_F(DtmfSenderTest, InsertDtmfWithDefaultCommaDelay) {
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000317 std::string tones = "3,4";
318 int duration = 100;
319 int inter_tone_gap = 50;
Aaron Alaniz529d8862020-01-21 03:09:47 +0000320 int default_comma_delay = webrtc::DtmfSender::kDtmfDefaultCommaDelayMs;
321 EXPECT_EQ(dtmf_->comma_delay(), default_comma_delay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000322 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
deadbeefe7fc7d52016-10-28 13:53:08 -0700323 EXPECT_TRUE_SIMULATED_WAIT(observer_->completed(), kMaxWaitMs, fake_clock_);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000324
325 VerifyOnProvider(tones, duration, inter_tone_gap);
326 VerifyOnObserver(tones);
Aaron Alaniz529d8862020-01-21 03:09:47 +0000327 EXPECT_EQ(dtmf_->comma_delay(), default_comma_delay);
328}
329
330TEST_F(DtmfSenderTest, InsertDtmfWithNonDefaultCommaDelay) {
331 std::string tones = "3,4";
332 int duration = 100;
333 int inter_tone_gap = 50;
334 int default_comma_delay = webrtc::DtmfSender::kDtmfDefaultCommaDelayMs;
335 int comma_delay = 500;
336 EXPECT_EQ(dtmf_->comma_delay(), default_comma_delay);
337 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap, comma_delay));
338 EXPECT_TRUE_SIMULATED_WAIT(observer_->completed(), kMaxWaitMs, fake_clock_);
339
340 VerifyOnProvider(tones, duration, inter_tone_gap, comma_delay);
341 VerifyOnObserver(tones);
342 EXPECT_EQ(dtmf_->comma_delay(), comma_delay);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000343}
344
345TEST_F(DtmfSenderTest, TryInsertDtmfWhenItDoesNotWork) {
346 std::string tones = "3,4";
347 int duration = 100;
348 int inter_tone_gap = 50;
deadbeef20cb0c12017-02-01 20:27:00 -0800349 provider_->SetCanInsertDtmf(false);
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000350 EXPECT_FALSE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
351}
352
353TEST_F(DtmfSenderTest, InsertDtmfWithInvalidDurationOrGap) {
354 std::string tones = "3,4";
dminor588101c2017-03-28 11:18:32 -0700355 int duration = 40;
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000356 int inter_tone_gap = 50;
357
358 EXPECT_FALSE(dtmf_->InsertDtmf(tones, 6001, inter_tone_gap));
dminor588101c2017-03-28 11:18:32 -0700359 EXPECT_FALSE(dtmf_->InsertDtmf(tones, 39, inter_tone_gap));
Harald Alvestrand52e58522018-02-20 08:15:36 +0100360 EXPECT_FALSE(dtmf_->InsertDtmf(tones, duration, 29));
Aaron Alaniz529d8862020-01-21 03:09:47 +0000361 EXPECT_FALSE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap, 29));
henrike@webrtc.org28e20752013-07-10 00:45:36 +0000362
363 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
364}
Harald Alvestrand1e0c8042018-03-06 10:51:27 +0100365
366TEST_F(DtmfSenderTest, InsertDtmfSendsAfterWait) {
367 std::string tones = "ABC";
368 int duration = 100;
369 int inter_tone_gap = 50;
370 EXPECT_TRUE(dtmf_->InsertDtmf(tones, duration, inter_tone_gap));
Steve Antonb983bae2018-06-20 11:16:53 -0700371 VerifyExpectedState("ABC", duration, inter_tone_gap);
Harald Alvestrand1e0c8042018-03-06 10:51:27 +0100372 // Wait until the first tone got sent.
373 EXPECT_TRUE_SIMULATED_WAIT(observer_->tones().size() == 1, kMaxWaitMs,
374 fake_clock_);
Steve Antonb983bae2018-06-20 11:16:53 -0700375 VerifyExpectedState("BC", duration, inter_tone_gap);
Harald Alvestrand1e0c8042018-03-06 10:51:27 +0100376}