1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements. See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership. The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License. You may obtain a copy of the License at
8//
9// http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied. See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18library thrift.test.transport.t_socket_transport_test;
19
20import 'dart:async';
21import 'dart:convert' show Encoding;
22import 'dart:convert' show Utf8Codec, BASE64;
23import 'dart:typed_data' show Uint8List;
24
25import 'package:http/http.dart' show BaseRequest;
26import 'package:http/http.dart' show Client;
27import 'package:http/http.dart' show Response;
28import 'package:http/http.dart' show StreamedResponse;
29import 'package:test/test.dart';
30import 'package:thrift/thrift.dart';
31
32void main() {
33  const utf8Codec = const Utf8Codec();
34
35  group('THttpClientTransport', () {
36    FakeHttpClient client;
37    THttpClientTransport transport;
38
39    setUp(() {
40      client = new FakeHttpClient(sync: false);
41      var config = new THttpConfig(Uri.parse('http://localhost'), {});
42      transport = new THttpClientTransport(client, config);
43    });
44
45    test('Test transport sends body', () async {
46      var expectedText = 'my request';
47      transport.writeAll(utf8Codec.encode(expectedText));
48
49      expect(client.postRequest, isEmpty);
50
51      await transport.flush();
52
53      expect(client.postRequest, isNotEmpty);
54
55      var requestText =
56          utf8Codec.decode(BASE64.decode(client.postRequest));
57      expect(requestText, expectedText);
58    });
59
60    test('Test transport receives response', () async {
61      var expectedText = 'my response';
62      var expectedBytes = utf8Codec.encode(expectedText);
63      client.postResponse = BASE64.encode(expectedBytes);
64
65      transport.writeAll(utf8Codec.encode('my request'));
66      expect(transport.hasReadData, isFalse);
67
68      await transport.flush();
69
70      expect(transport.hasReadData, isTrue);
71
72      var buffer = new Uint8List(expectedBytes.length);
73      transport.readAll(buffer, 0, expectedBytes.length);
74
75      var bufferText = utf8Codec.decode(buffer);
76      expect(bufferText, expectedText);
77    });
78  });
79
80  group('THttpClientTransport with multiple messages', () {
81    FakeHttpClient client;
82    THttpClientTransport transport;
83
84    setUp(() {
85      client = new FakeHttpClient(sync: true);
86      var config = new THttpConfig(Uri.parse('http://localhost'), {});
87      transport = new THttpClientTransport(client, config);
88    });
89
90    test('Test read correct buffer after flush', () async {
91      String bufferText;
92      var expectedText = 'response 1';
93      var expectedBytes = utf8Codec.encode(expectedText);
94
95      // prepare a response
96      transport.writeAll(utf8Codec.encode('request 1'));
97      client.postResponse = BASE64.encode(expectedBytes);
98
99      Future responseReady = transport.flush().then((_) {
100        var buffer = new Uint8List(expectedBytes.length);
101        transport.readAll(buffer, 0, expectedBytes.length);
102        bufferText = utf8Codec.decode(buffer);
103      });
104
105      // prepare a second response
106      transport.writeAll(utf8Codec.encode('request 2'));
107      var response2Bytes = utf8Codec.encode('response 2');
108      client.postResponse = BASE64.encode(response2Bytes);
109      await transport.flush();
110
111      await responseReady;
112      expect(bufferText, expectedText);
113    });
114  });
115}
116
117class FakeHttpClient implements Client {
118  String postResponse = '';
119  String postRequest = '';
120
121  final bool sync;
122
123  FakeHttpClient({this.sync: false});
124
125  Future<Response> post(url,
126      {Map<String, String> headers, body, Encoding encoding}) {
127    postRequest = body;
128    var response = new Response(postResponse, 200);
129
130    if (sync) {
131      return new Future.sync(() => response);
132    } else {
133      return new Future.value(response);
134    }
135  }
136
137  Future<Response> head(url, {Map<String, String> headers}) =>
138      throw new UnimplementedError();
139
140  Future<Response> get(url, {Map<String, String> headers}) =>
141      throw new UnimplementedError();
142
143  Future<Response> put(url,
144          {Map<String, String> headers, body, Encoding encoding}) =>
145      throw new UnimplementedError();
146
147  Future<Response> patch(url,
148          {Map<String, String> headers, body, Encoding encoding}) =>
149      throw new UnimplementedError();
150
151  Future<Response> delete(url, {Map<String, String> headers}) =>
152      throw new UnimplementedError();
153
154  Future<String> read(url, {Map<String, String> headers}) =>
155      throw new UnimplementedError();
156
157  Future<Uint8List> readBytes(url, {Map<String, String> headers}) =>
158      throw new UnimplementedError();
159
160  Future<StreamedResponse> send(BaseRequest request) =>
161      throw new UnimplementedError();
162
163  void close() => throw new UnimplementedError();
164}
165