dwyl / flutter-image-upload-demo

πŸ“±πŸ–ΌοΈ ⬆️ ☁️ Quick demo Flutter App showcasing uploading images to S3
https://dwyl.github.io/flutter-image-upload-demo/
8 stars 0 forks source link

Epic: Upload Images from `Flutter` App to `S3` via `Phoenix` #1

Closed nelsonic closed 1 year ago

nelsonic commented 1 year ago

Once we have basic image uploading working in Phoenix + LiveView #51 (and deployed to Fly.io) πŸš€ The next logical step is to implement a Flutter front-end. πŸ“± The most difficult part of this is: a) uploading the img data to the Phoenix backend: https://kashifchandio.medium.com/upload-images-to-a-rest-api-with-flutter-using-http-61713964e1c appears to be a good starting point. But please do your own research to find any relevant sample code. πŸ™ b) Securing the uploads so that random people can't send data to the Phoenix upload API/backend. This should probably be something we handle server side. See: https://github.com/dwyl/image-uploads/issues/53 c) Visual feedback for the uploader indicating the approximate time it will take to process.

Todo

image

Fellow Tuga @miguelpruivo - rising star of @FlutterPortugal - he's built: flutter_file_picker
looks well-documented, tested & maintained. 😍 We can use it for the file-picking part.

Note: we aren't building imgur but certainly the foundation of it. 😜

LuchoTurtle commented 1 year ago

I have a basic app going but the reason it's taking longer it's because of testing. flutter_file_picker doesn't have a mock, so I have to use a package like Mockito to try and get a mocked class to substitute it in test environments. This entails refactoring the code so the function is mockable.

Because flutter_file_picker is a static class, it can't be mocked. So I'm trying to get a workaround going (like https://github.com/dart-lang/mockito/issues/214) so I can properly mock the file picker and http requests in widget tests.

nelsonic commented 1 year ago

Good progress. :shipit: Excuse my ignorance, why do you need to mock the file_picker? πŸ’­

LuchoTurtle commented 1 year ago

I need to be able to mock the result of the file_picker so I'm able to test whether or not the person chose an image or not. If they do, I need to use this value to also mock the HTTP request that I make for uploading the image. No way I can test the behaviour without mocking because I can't "choose an image" in a unit test.

nelsonic commented 1 year ago

Hmm ... πŸ’­ Please consider opening an issue on https://github.com/miguelpruivo/flutter_file_picker/issues to ask other people how they are mocking the library for testing purposes. If there isn't a well defined way of doing it, we could offer to create one (PR).

LuchoTurtle commented 1 year ago

One guy opened an issue in https://github.com/miguelpruivo/flutter_file_picker/issues/941 and that's what I'm essentially doing. I'm trying to mock it but mockito has a learning curve that I've yet to master properly (even though I've used it in the past :)

nelsonic commented 1 year ago

Yeah, that issue https://github.com/miguelpruivo/flutter_file_picker/issues/941 doesn't appear to have a definitive answer. πŸ€·β€β™‚οΈ And it's 16 months later so there may have been someone else who has figured it out. ⏳ It's worth re-phrasing the question and asking for guidance. πŸ™ Explicitly link to the old unresolved issue and say you read it but don't feel like there is a canonical solution. πŸ”—

LuchoTurtle commented 1 year ago

Created an issue in https://github.com/miguelpruivo/flutter_file_picker/issues/1306

LuchoTurtle commented 1 year ago

I'm trying to mock the behaviour and, while I've had some progress (had to refactor the code so I could make new requests, injecting the http.Client instead of http.MultipartRequest to later be mocked), the test "skips" when file.readAsBytes() is called.

Will follow https://stackoverflow.com/questions/64031671/flutter-readasbytes-readasstring-in-widget-tests to see if anything works.

nelsonic commented 1 year ago

IMO: mocks are of limited value in this project unless your tests are uploading hundreds of images. You might as well do end-to-end tests uploading images to the real API on Fly.io πŸ’­ What's the downside to not mocking the uploads? πŸ€”

LuchoTurtle commented 1 year ago

Besides HTTP requests being blocked when running flutter test by default, even if we wanted to make real requests to the API, it misses the point of testing the behavior of this project. We don't know if the API will always be up and it might crash the unit tests.

On top of this, I think this is a good exercise and great for future reference to mocking this behaviour with mockito and widgets that make use of Network (which is the case here, since we're using Image.network).

LuchoTurtle commented 1 year ago

Tests should be all running correctly. I'm still not finished, as I:

nelsonic commented 1 year ago

Having a real-world test that exercises an existing API - that we control - is highly desirable. Yes, it makes the tests tightly coupled with the API but won't the App be coupled with the backend...? πŸ’­ Knowing what the round trip latency of an API request is and keeping a close eye on the performance is a major win.

Thanks for sharing that link @LuchoTurtle πŸ”—

No disrespect intended to the people who made that decision, but ... Having a default 400 response for all HTTP requests in tests https://github.com/flutter/flutter/blame/63aa5b3647dbd912a02f7545fc0101003cb3adc4/packages/flutter_test/lib/src/binding.dart#L1570 is one of the stupidest and most pointless things I've read in a loooong time. πŸ€¦β€β™‚οΈ In what scenario is that helpful for building real-world apps? Which API/ service always returns a 400 error...?! πŸ€·β€β™‚οΈ

This is the kind of (moronic) "best practice" that only makes sense in some academic ivory tower. πŸ‘¨β€πŸ« It's nanny state BS that would make me stop using a framework. πŸ‘Ž If they're that stupid to block HTTP requests from tests - that will trip up many new devs, 😒 what other kinds of dev-unfriendly decisions have they made that we will only discover years later?! πŸ€¦β€β™‚οΈ