Implement more of FetchOptions#602
Conversation
27f1a69 to
f765971
Compare
|
Don't merge yet. |
4d24efb to
ade8214
Compare
|
@jstarry @deniskolodin I am meeting issues with manual redirect, it seems that when a redirect happens while manual redirect is enabled, it throws an error but I can't catch it with Yew. |
33fc675 to
c61fdf6
Compare
|
@Leo-LB sorry for the delays on this, can you provide some steps on how you have been testing manual redirect? I'd be happy to look into it if you can help me get started :) |
@jstarry Clone https://github.com/leo-lb/random-imgur-wall and use |
|
No confusion, just lack of time. I'm planning on getting this in before v0.11 🤞 |
|
I think this PR can be merged as-is, the bug I was being hit by isnt part of the changes introduced by this PR. Rather, I should open an issue about it. It happens on fetch's redirects but this does not do anything about redirects. |
|
@Leo-LB ok, as long as CI passes! Could you please rebase and push? |
c61fdf6 to
f52854c
Compare
|
@jstarry Done! It should pass CI! |
|
I think slapping a |
07e4996 to
47f4aef
Compare
|
@hgzimmerman I followed what was on other structures, CI now passes! |
|
I would love if this PR included some tests as well 😉 |
|
To test this, one would need to include a web server inside the tests. Is there anything that tests code with networking yet? |
|
Or we can use: https://httpbin.org/ -- is that acceptable? |
| println!("{:#?}", resp); | ||
| }); | ||
| let task = FetchService::new().fetch_with_options(request, options, callback); | ||
| while task.is_active() {} |
There was a problem hiding this comment.
How can I force the FetchTask to execute? Looping doesnt do it.
There was a problem hiding this comment.
I would think that should execute without the while. I assume you aren't seeing a print in the console because a shim between rust's println and the browser console isn't set up, so by default, it should do nothing (although I may be wrong).
I don't recall how to do that with println, but https://github.com/yewstack/web_logger does this for the logging facilities in the log crate.
I may be entirely off-base though, and it isn't making the request at all.
The plain fetch is used here in this example: https://github.com/yewstack/yew/blob/master/examples/dashboard/src/lib.rs#L117
There was a problem hiding this comment.
Okay I see, I would think that without the loop, FetchTask would get dropped and immediately canceled.
In the example you linked, the FetchTask is returned and stored then, it does not get dropped.
I do not know how I can do that in the context of a test.
Also, I figured I could maybe use stdweb's support for PromiseFutures (koute/stdweb#103) and convert the fetch "handle" to a future I can await but somehow there's nothing about them in stdweb's released documentation? https://docs.rs/stdweb/0.4.20/stdweb/?search=future https://docs.rs/stdweb/0.4.20/stdweb/?search=promise
There was a problem hiding this comment.
Ah, I forgot about that - and the example I provided looks suspicious - that fetch task handle should be preserved in the model in some way.
So yeah, I think looping should be the opportune way to handle that in a test environment - but maybe not with is_active() as I don't think that is set to false when the request completes - only when it is explicitly cancelled.
Maybe the best code would be something along the lines of:
let mut stop = false;
let callback = Callback::from(move |resp: Response<Result<String, failure::Error>>| {
stop = true; // Not sure if the Callback's FnOnce bound will allow this to be satisfied
});
let task = FetchService::new().fetch_with_options(request, options, callback);
while !stop { }There was a problem hiding this comment.
Nope, it doesnt allow it, unfortunately.
There was a problem hiding this comment.
I tried with an Rc<RefCell<_>> and it loops indefinitely.
use std::cell::RefCell;
use std::rc::Rc;
#[cfg(feature = "wasm_test")]
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::callback::Callback;
use yew::format::Nothing;
use yew::services::fetch::{self, FetchOptions, Response};
use yew::services::FetchService;
use yew::services::Task;
#[cfg(feature = "wasm_test")]
wasm_bindgen_test_configure!(run_in_browser);
#[test]
fn fetch_redirect_follow() {
let request = fetch::Request::get("https://httpbin.org/relative-redirect/1")
.body(Nothing)
.unwrap();
let options = FetchOptions {
redirect: Some(fetch::Redirect::Follow),
..FetchOptions::default()
};
let is_done = Rc::new(RefCell::new(false));
let is_done_callback = is_done.clone();
let callback = Callback::from(move |resp: Response<Result<String, failure::Error>>| loop {
match is_done_callback.try_borrow_mut() {
Ok(mut is_done_callback) => {
*is_done_callback = true;
return;
}
_ => {}
}
});
let task = FetchService::new().fetch_with_options(request, options, callback);
loop {
match is_done.try_borrow() {
Ok(is_done) if *is_done => return,
_ => {}
}
}
}There was a problem hiding this comment.
When I monitor traffic with Wireshark the request does happen though.
There was a problem hiding this comment.
I also tried with a full Yew app:
#[cfg(feature = "wasm_test")]
use wasm_bindgen_test::{wasm_bindgen_test as test, wasm_bindgen_test_configure};
use yew::format::Nothing;
use yew::services::fetch::{self, FetchOptions, FetchTask, Response};
use yew::services::FetchService;
#[cfg(feature = "wasm_test")]
wasm_bindgen_test_configure!(run_in_browser);
#[test]
fn fetch_redirect_follow() {
use yew::{html, Component, ComponentLink, Html, ShouldRender};
struct Model {
link: ComponentLink<Self>,
task: Option<FetchTask>,
}
enum Msg {
TestSuccess,
TestFail(Response<Result<String, failure::Error>>),
}
impl Component for Model {
type Message = Msg;
type Properties = ();
fn create(_: Self::Properties, link: ComponentLink<Self>) -> Self {
let mut model = Model { link, task: None };
model.task = Some(
FetchService::new().fetch_with_options(
fetch::Request::get("https://httpbin.org/relative-redirect/1")
.body(Nothing)
.unwrap(),
FetchOptions {
redirect: Some(fetch::Redirect::Follow),
..FetchOptions::default()
},
model
.link
.callback(move |resp: Response<Result<String, failure::Error>>| {
if resp.status().is_success() {
Msg::TestSuccess
} else {
Msg::TestFail(resp)
}
}),
),
);
model
}
fn update(&mut self, msg: Self::Message) -> ShouldRender {
match msg {
Msg::TestSuccess => {
self.task = None;
false
}
Msg::TestFail(resp) => {
self.task = None;
panic!("{:?}", resp);
}
}
}
fn view(&self) -> Html {
html! {}
}
}
yew::start_app::<Model>();
}And on test execution it returns:
Running headless tests in Chrome on `http://127.0.0.1:36599/`
Try find `webdriver.json` for configure browser's capabilities:
Not found
driver status: signal: 9
driver stdout:
Starting ChromeDriver 78.0.3904.105 (60e2d8774a8151efa6a00b1f358371b1e0e07ee2-refs/branch-heads/3904@{#877}) on port 36599
Only local connections are allowed.
Please protect ports used by ChromeDriver and related test frameworks to prevent access by malicious code.
Error: invalid type: map, expected a string at line 1 column 68
error: test failed, to rerun pass '--test fetch_service'
There was a problem hiding this comment.
Evidently channels aren't supported.
I'm going to defer to @jstarry at this point as I don't have experience in writing tests in this context.
There was a problem hiding this comment.
It looks more supported to write asynchronous tests to test asynchronous functions. https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/asynchronous-tests.html
Problem: Yew implements callback based services and not Futures.
llebout
left a comment
There was a problem hiding this comment.
I would need some help here
|
@jstarry Hey! Seems like there is some work to do on making the Yew<->JS interop side more testable as a whole 😅 -- PS: 🎉 on release |
Yeah there really is! Testing has been neglected for awhile 😅 Sorry this didn't make it into the latest release! |
Add referrer, referrer_policy and integrity
4128340 to
5eb8a20
Compare
|
@Leo-LB today I added some test utils for wrapping a task callback into a future so that we can use async tests. Could you please pull my changes and finish adding tests for |
@jstarry |
|
On the tests, I am getting these errors: Is that expected? EDIT: |
|
@jstarry Added. And I tried changing the policy and running the tests in a normal browser by not specifying an headless web driver and it seems that in Chromium, seen in the dev tools Network tab, it's not being changed. I don't know why exactly, if it's Chromium ignoring the option or that the code does not work. |
b693ee7 to
b7d7a00
Compare
|
@jstarry I made some additional tests with a non-headless browser and I could determine that the |
|
@jstarry I added tests for |
ee239df to
f3e88f5
Compare
|
@jstarry So everything's good! |
f3e88f5 to
9c84d9e
Compare
9c84d9e to
da83450
Compare
|
@Leo-LB thanks for all the tests!! This is the start of a new era of Yew 🎉 |

Fixes #601
Add referrer, referrer_policy and integrity