Mock StreamedResponse with http package - flutter

Using the http.testing library to mock http requests that return Responses work. That's fine as in the example:
import 'dart:convert';
import 'package:http/testing.dart';
var client = MockClient((request) async {
if (request.url.path != "/data.json") {
return Response("", 404);
}
return Response(
json.encode({
'numbers': [1, 4, 15, 19, 214]
}),
200,
headers: {'content-type': 'application/json'});
});
I'm also using http requests that return StreamedResponses, like:
http.StreamedResponse response = await client.send(request);
How could I mock these kind of responses using the http.testing library or maybe even with mockito or another package?
I have tried to mock it with mockito before but I haven't figured out how to do it.
when(
client.send(any),
).thenAnswer((_) async => MockStreamedResponse());
The previous code doesn't even seem to mock the send method.
and I don't even know how to try with http.testing library because I don't have a source to generate the StreamedResponse.
import 'dart:convert';
import 'package:http/testing.dart';
var client = MockClient.streaming((request, bodyStream) => ???);
How could I create a mock or a StreamedResponse instance for my flutter test?

Related

How to get headers from AxiosResponse-Observable?

Using NestJS, Axios returns an Observable<AxiosResponse>.
How can I get the headers of a GET- or HEAD-Request?
Lets say I make a HEAD-request:
import { HttpService } from '#nestjs/axios';
const observable = this.httpService.head(uri);
How can I get the headers from the result?
Update:
I found a nice workaround that just works with a single line of code.
There is another library called https with is more powerful:
import http from "https";
await http.request(uri, { method: 'HEAD' }, (res) => {
console.log(res.headers);
}).on('error', (err) => {
console.error(err);
}).end();
The headers of the response are available in the subscribe callback with the headers property.
this.httpService.head(uri).subscribe(res => {
console.log(res.headers)
});
Playground
According to https://github.com/axios/axios#request-config:
For request headers you should use something like this:
this.httpService.axiosRef.interceptors.request.use(function (config) {
// Do something before request is sent
console.log(config);
return config;
}, function (error) {
// Do something with request error
return Promise.reject(error);
});
You should use it onModuleInit (to prevent working a few interceptors in a time)
Also you can make own module like in this answer: https://stackoverflow.com/a/72543771/4546382
For the response headers you can just use response.headers

Get Headers for API Authentication [duplicate]

I'm working on a simple Flutter mobile app that needs to call out to an API that uses Basic Auth.
I can hit the API in Postman using email & password credentials and it encodes the email & password in Base64 (I assume with a ":" separating) before performing the request.
I'm not sure how to do this in Flutter / Dart...
I've tinkered with the http package and tried to do the Base64 encoding... but I just get back errors from the server.
Can anyone provide some guidance or an example for a basic auth request?
Assuming that your server expects that the username:password combo will be encode it UTF-8 (see RFC 7617 for more details) then use this:
import 'dart:convert';
import 'package:http/http.dart';
main() async {
String username = 'test';
String password = '123£';
String basicAuth =
'Basic ' + base64.encode(utf8.encode('$username:$password'));
print(basicAuth);
Response r = await get(Uri.parse('https://api.somewhere.io'),
headers: <String, String>{'authorization': basicAuth});
print(r.statusCode);
print(r.body);
}
I know it's late but I am posting this if it can help others.
import 'dart:convert';
var auth = 'Basic '+base64Encode(utf8.encode('$username:$password'));
Future<Response> callAPI(param) async {
await dio.post('/api/test',
data: {'param': param},
options: Options(headers: <String, String>{'authorization': auth}));
}

How to send a message in the Slack channel using Flutter?

I am creating an attendance app in which if an employee got the approval on leave request, then the app should send a message in the Slack channel.
I have seen this flutter package on the pub but it is not very helpful:-
https://pub.dev/packages/flutter_slack_oauth
Any idea on how I can send a message in the Slack channel using Flutter?
Finally got the answer, and wants to share :)
Here is the slack API URL to create a new app:-
https://api.slack.com/apps
After creating a new app, activate the Incoming Webhooks feature:-
Grab the webhook URL for your workspace, and make a request via this Flutter function:-
import 'dart:convert';
import 'package:http/http.dart' as http;
sendSlackMessage(String messageText) {
//Slack's Webhook URL
var url = 'https://hooks.slack.com/services/TA******JS/B0**********SZ/Kk*******************1D';
//Makes request headers
Map<String, String> requestHeader = {
'Content-type': 'application/json',
};
var request = {
'text': messageText,
};
var result = http
.post(url, body: json.encode(request), headers: requestHeader)
.then((response) {
print(response.body);
});
print(result);
}
You can also use slack post api for posting message.
var url = "https://slack.com/api/chat.postMessage";
var headers: {
"Content-type": "application/json",
"Authorization": 'Bearer $oAuthToken'
};
var body = {"channel": "Your_Channel_Id", "text": ":tada: :tada: :tada:", "as_user": true};
Add scope chat:write in your app configuration.
And now you will be able to send message to you channel. Hopefully it helps.

Unable to POST using Angular 7 : Header Does not work

I'm currently building out an Angular 7 App, and trying to implement the following HTTP API Call Scenario:
Request for an Application Token:
https://(URL)/token
Request Type: POST
Headers:
Accept: application/json
Request Body: empty
I have a Service class in the Angular app and the code is as follows:
import { HttpClient } from '#angular/common/http';
import { HttpHeaders } from '#angular/common/http';
The requestToken function is implemented as follows:
requestToken() {
let headers = new HttpHeaders();
headers = headers.set('Accept', 'application/json');
return this.http.post(this.configUrl + '/token', headers);
}
The Service is then called in one of the components in the App:-
getToken() {
this.service.requestToken().subscribe( res => {
console.log(res);
}, error => {
console.log(error);
});
}
When I run the App, I get a 404 Not Found error in the console. I used Postman to make an API call, setting the 'Accept' header to 'application/json' and then specifying url as https://(URL)/token and I successfully get a response. But I'm unable to make it work via Angular.
Is there something else I need to do to set the header properly in Angular? Also, I have no way to check if CORS has been enabled on the API server as this is a third-party service which I'm trying to call.
Any help would be appreciated. Thanks
Solved the problem. Changed the POST call to the following:
requestToken() {
const httpHeaders = new HttpHeaders({
'Accept': 'application/json'
});
return this.http.post(this.configUrl + '/token', { body: ''}, { headers: httpHeaders });
}
Had to add an empty 'body' parameter

Can't set Authentication header for Apollo client

I'm working on a Laravel application that uses React and Redux on the client side, with the React preset and Mix. I've decided to try out GraphQL for the API rather than the usual REST API approach and it's working OK so far. However, I've now got stuck.
I'm using Apollo as my HTTP client since it's built for working with GraphQL. In the past I've used JWT Auth for securing APIs, so naturally I've gone for that approach here too, since implementation is just a case of adding an appropriate header. I've followed the instruction on setting headers with Apollo, but the headers aren't getting set. Here's the JS file in question:
import LinkList from './components/LinkList';
import React from 'react';
import ReactDOM from 'react-dom';
import {Container} from './container';
import {createStore} from 'redux';
import reducer from './reducer';
import {Provider} from 'react-redux';
import {fromJS} from 'immutable';
import ApolloClient from 'apollo-boost';
import gql from 'graphql-tag';
import { createHttpLink } from 'apollo-link-http';
import { setContext } from 'apollo-link-context';
import { InMemoryCache } from 'apollo-cache-inmemory';
const httpLink = createHttpLink({
uri: window.initialData.graphql_route
});
const authLink = setContext((_, { headers }) => {
const token = window.initialData.jwt;
// return the headers to the context so httpLink can read them
return {
headers: {
...headers,
authorization: token ? `Bearer ${token}` : "",
}
}
});
const client = new ApolloClient({
link: authLink.concat(httpLink),
cache: new InMemoryCache()
});
client.query({
query: gql`{
links {
id
title
link
}}`
}).then(result => console.log(result));
const store = createStore(
reducer,
fromJS(window.initialData),
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
if (document.getElementById('list')) {
ReactDOM.render(
<Provider store={store}>
<Container />
</Provider>,
document.getElementById('list')
);
}
I populate window.initialData in the view, and that contains the necessary data, including the JWT token as window.initialData.jwt. Setting a breakpoint inside the definition of authLink does nothing, implying that it never gets called.
Any idea what's gone wrong? I've followed the examples in the documentation pretty closely, so all I can think of is that they might be put of date.
Info: Don't save your token in the localStorage Is it safe to store a JWT in localStorage with ReactJS?
You are using the ApolloClient from 'apollo-boost', but your token configuration is for another ApolloClient, the { ApolloClient } from 'apollo-client'.
If you want to save the token using the ApolloClient from apollo-boost:
const client = new ApolloClient({
uri: ...,
request: async operation => {
const token = localStorage.getItem('token');
operation.setContext({
headers: {
authorization: token ? `Bearer ${token}` : ''
}
});
}
});
Apollo Boost migration