blob: 3d16a73ae8642a575a1da53e3fc47a4510eff6b7 [file] [log] [blame]
// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
import 'package:http2/src/frames/frames.dart';
import 'package:http2/src/hpack/hpack.dart';
import 'package:http2/src/settings/settings.dart';
import 'package:mockito/mockito.dart';
import 'package:test/test.dart';
import '../error_matchers.dart';
void main() {
group('settings-handler', () {
var pushSettings = [Setting(Setting.SETTINGS_ENABLE_PUSH, 0)];
var invalidPushSettings = [Setting(Setting.SETTINGS_ENABLE_PUSH, 2)];
var setMaxTable256 = [Setting(Setting.SETTINGS_HEADER_TABLE_SIZE, 256)];
test('successful-setting', () async {
var writer = FrameWriterMock();
var sh = SettingsHandler(
HPackEncoder(), writer, ActiveSettings(), ActiveSettings());
// Start changing settings.
var changed = sh.changeSettings(pushSettings);
verify(writer.writeSettingsFrame(pushSettings)).called(1);
verifyNoMoreInteractions(writer);
// Check that settings haven't been applied.
expect(sh.acknowledgedSettings.enablePush, true);
// Simulate remote end to respond with an ACK.
var header =
FrameHeader(0, FrameType.SETTINGS, SettingsFrame.FLAG_ACK, 0);
sh.handleSettingsFrame(SettingsFrame(header, []));
await changed;
// Check that settings have been applied.
expect(sh.acknowledgedSettings.enablePush, false);
});
test('ack-remote-settings-change', () {
var writer = FrameWriterMock();
var sh = SettingsHandler(
HPackEncoder(), writer, ActiveSettings(), ActiveSettings());
// Check that settings haven't been applied.
expect(sh.peerSettings.enablePush, true);
// Simulate remote end by setting the push setting.
var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
sh.handleSettingsFrame(SettingsFrame(header, pushSettings));
// Check that settings have been applied.
expect(sh.peerSettings.enablePush, false);
verify(writer.writeSettingsAckFrame()).called(1);
verifyNoMoreInteractions(writer);
});
test('invalid-remote-ack', () {
var writer = FrameWriterMock();
var sh = SettingsHandler(
HPackEncoder(), writer, ActiveSettings(), ActiveSettings());
// Simulates ACK even though we haven't sent any settings.
var header =
FrameHeader(0, FrameType.SETTINGS, SettingsFrame.FLAG_ACK, 0);
var settingsFrame = SettingsFrame(header, const []);
expect(() => sh.handleSettingsFrame(settingsFrame),
throwsA(isProtocolException));
verifyZeroInteractions(writer);
});
test('invalid-remote-settings-change', () {
var writer = FrameWriterMock();
var sh = SettingsHandler(
HPackEncoder(), writer, ActiveSettings(), ActiveSettings());
// Check that settings haven't been applied.
expect(sh.peerSettings.enablePush, true);
// Simulate remote end by setting the push setting.
var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
var settingsFrame = SettingsFrame(header, invalidPushSettings);
expect(() => sh.handleSettingsFrame(settingsFrame),
throwsA(isProtocolException));
verifyZeroInteractions(writer);
});
test('change-max-header-table-size', () {
var writer = FrameWriterMock();
var mock = HPackEncoderMock();
var sh =
SettingsHandler(mock, writer, ActiveSettings(), ActiveSettings());
// Simulate remote end by setting the push setting.
var header = FrameHeader(6, FrameType.SETTINGS, 0, 0);
var settingsFrame = SettingsFrame(header, setMaxTable256);
sh.handleSettingsFrame(settingsFrame);
verify(mock.updateMaxSendingHeaderTableSize(256)).called(1);
verify(writer.writeSettingsAckFrame()).called(1);
verifyNoMoreInteractions(mock);
verifyNoMoreInteractions(writer);
});
});
}
class FrameWriterMock extends Mock implements FrameWriter {}
class HPackEncoderMock extends Mock implements HPackEncoder {}