From 62c11bee93f7553c28eb1130e74b4328fb427e24 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Mon, 27 Dec 2021 16:34:40 -0400 Subject: [PATCH 01/13] remove redudant media type --- .../lib/src/media/media_types.dart | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 packages/stream_feed_flutter/lib/src/media/media_types.dart diff --git a/packages/stream_feed_flutter/lib/src/media/media_types.dart b/packages/stream_feed_flutter/lib/src/media/media_types.dart deleted file mode 100644 index e56926a83..000000000 --- a/packages/stream_feed_flutter/lib/src/media/media_types.dart +++ /dev/null @@ -1,14 +0,0 @@ -/// Enumerates the types of supported media in Feeds. -enum MediaType { - /// Audio media - audio, - - /// Image media - image, - - /// Video media - video, - - /// Unknown or unsupported media type - unknown -} From 2bd2e54e9128d9e8ba7b07ed51caab1cccaf666b Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Thu, 6 Jan 2022 08:58:54 -0400 Subject: [PATCH 02/13] remove token from constructor --- .../lib/src/client/stream_feed_client.dart | 2 +- .../src/client/stream_feed_client_impl.dart | 58 +++++++++++++------ .../test/stream_feed_client_test.dart | 18 ++---- 3 files changed, 48 insertions(+), 30 deletions(-) diff --git a/packages/stream_feed/lib/src/client/stream_feed_client.dart b/packages/stream_feed/lib/src/client/stream_feed_client.dart index 763a250be..1bff85d44 100644 --- a/packages/stream_feed/lib/src/client/stream_feed_client.dart +++ b/packages/stream_feed/lib/src/client/stream_feed_client.dart @@ -69,7 +69,7 @@ abstract class StreamFeedClient { }) => StreamFeedClientImpl( apiKey, - userToken: token, + // userToken: token, secret: secret, appId: appId, options: options, diff --git a/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart b/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart index 791e06a90..36f4555f6 100644 --- a/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart +++ b/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart @@ -38,8 +38,6 @@ class StreamFeedClientImpl implements StreamFeedClient { StreamFeedClientImpl( this.apiKey, { this.secret, - this.userToken, //TODO(sacha): remove this and call _ensureCredentials - //in the getters instead (collections etc) this.appId, this.fayeUrl = 'wss://faye-us-east.stream-io-api.com/faye', this.runner = Runner.client, @@ -48,7 +46,6 @@ class StreamFeedClientImpl implements StreamFeedClient { StreamAPI? api, StreamHttpClientOptions? options, }) { - assert(_ensureCredentials(), ''); _logger = Logger.detached('📜')..level = logLevel; _logger.onRecord.listen(logHandlerFunction ?? _defaultLogHandler); _logger.info('instantiating new client'); @@ -72,7 +69,8 @@ class StreamFeedClientImpl implements StreamFeedClient { case Runner.client: if (userToken == null) { throw AssertionError( - '`userToken` must be provided while running on client-side', + '`userToken` must be provided while running on client-side' + 'please make sure to call client.setUser', ); } if (secret != null) { @@ -146,6 +144,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override BatchOperationsClient get batch { + assert(_ensureCredentials(), ''); assert( runner == Runner.server, "You can't use batch operations client side", @@ -154,29 +153,44 @@ class StreamFeedClientImpl implements StreamFeedClient { } @override - CollectionsClient get collections => - CollectionsClient(_api.collections, userToken: userToken, secret: secret); + CollectionsClient get collections { + assert(_ensureCredentials(), ''); + return CollectionsClient(_api.collections, + userToken: userToken, secret: secret); + } @override - ReactionsClient get reactions => - ReactionsClient(_api.reactions, userToken: userToken, secret: secret); + ReactionsClient get reactions { + assert(_ensureCredentials(), ''); + return ReactionsClient(_api.reactions, + userToken: userToken, secret: secret); + } @override - PersonalizationClient get personalization => - PersonalizationClient(_api.personalization, - userToken: userToken, secret: secret); + PersonalizationClient get personalization { + assert(_ensureCredentials(), ''); + return PersonalizationClient(_api.personalization, + userToken: userToken, secret: secret); + } @override - StreamUser user(String userId) => - StreamUser(_api.users, userId, userToken: userToken, secret: secret); + StreamUser user(String userId) { + assert(_ensureCredentials(), ''); + return StreamUser(_api.users, userId, userToken: userToken, secret: secret); + } @override - FileStorageClient get files => - FileStorageClient(_api.files, userToken: userToken, secret: secret); + FileStorageClient get files { + assert(_ensureCredentials(), ''); + return FileStorageClient(_api.files, userToken: userToken, secret: secret); + } @override - ImageStorageClient get images => - ImageStorageClient(_api.images, userToken: userToken, secret: secret); + ImageStorageClient get images { + assert(_ensureCredentials(), ''); + return ImageStorageClient(_api.images, + userToken: userToken, secret: secret); + } Future _feedSubscriber( Token token, @@ -219,6 +233,7 @@ class StreamFeedClientImpl implements StreamFeedClient { String? userId, Token? userToken, ]) { + assert(_ensureCredentials(), ''); final id = FeedId(slug, _getUserId(userId)); return AggregatedFeed( id, @@ -235,6 +250,7 @@ class StreamFeedClientImpl implements StreamFeedClient { String? userId, Token? userToken, ]) { + assert(_ensureCredentials(), ''); final id = FeedId(slug, _getUserId(userId)); return FlatFeed( id, @@ -251,6 +267,7 @@ class StreamFeedClientImpl implements StreamFeedClient { String? userId, Token? userToken, ]) { + assert(_ensureCredentials(), ''); final id = FeedId(slug, _getUserId(userId)); return NotificationFeed( id, @@ -266,6 +283,7 @@ class StreamFeedClientImpl implements StreamFeedClient { String userId, { DateTime? expiresAt, }) { + assert(_ensureCredentials(), ''); assert( runner == Runner.server, "You can't use the `frontendToken` method client side", @@ -276,6 +294,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override Future og(String targetUrl) { + assert(_ensureCredentials(), ''); final token = userToken ?? TokenHelper.buildOpenGraphToken(secret!); return _api.openGraph(token, targetUrl); } @@ -286,6 +305,7 @@ class StreamFeedClientImpl implements StreamFeedClient { Map data, { bool getOrCreate = false, }) { + assert(_ensureCredentials(), ''); if (runner == Runner.client) { _logger.warning('We advice using `client.createUser` only server-side'); } @@ -296,9 +316,11 @@ class StreamFeedClientImpl implements StreamFeedClient { @override Future getUser(String id, {bool withFollowCounts = false}) { + assert(_ensureCredentials(), ''); if (runner == Runner.client) { _logger.warning('We advice using `client.getUser` only server-side'); } + final token = userToken ?? TokenHelper.buildUsersToken(secret!, TokenAction.read); return _api.users.get(token, id, withFollowCounts: withFollowCounts); @@ -306,6 +328,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override Future updateUser(String id, Map data) { + assert(_ensureCredentials(), ''); if (runner == Runner.client) { _logger.warning('We advice using `client.updateUser` only server-side'); } @@ -316,6 +339,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override Future deleteUser(String id) { + assert(_ensureCredentials(), ''); if (runner == Runner.client) { _logger.warning('We advice using `client.deleteUser` only server-side'); } diff --git a/packages/stream_feed/test/stream_feed_client_test.dart b/packages/stream_feed/test/stream_feed_client_test.dart index e19977567..cdff29683 100644 --- a/packages/stream_feed/test/stream_feed_client_test.dart +++ b/packages/stream_feed/test/stream_feed_client_test.dart @@ -113,8 +113,7 @@ void main() { test('openGraph', () async { final mockApi = MockAPI(); final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const targetUrl = 'targetUrl'; @@ -131,8 +130,7 @@ void main() { final mockUserAPI = MockUserAPI(); when(() => mockApi.users).thenReturn(mockUserAPI); final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const userId = 'test-user'; const data = { @@ -159,8 +157,7 @@ void main() { final mockUserAPI = MockUserAPI(); final token = TokenHelper.buildFrontendToken('secret', id); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const data = { 'name': 'John Doe', @@ -187,8 +184,7 @@ void main() { final mockUserAPI = MockUserAPI(); when(() => mockApi.users).thenReturn(mockUserAPI); final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const userId = 'test-user'; const data = { @@ -214,8 +210,7 @@ void main() { final mockUserAPI = MockUserAPI(); when(() => mockApi.users).thenReturn(mockUserAPI); final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const userId = 'test-user'; const data = { @@ -241,8 +236,7 @@ void main() { final mockUserAPI = MockUserAPI(); when(() => mockApi.users).thenReturn(mockUserAPI); final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = - StreamFeedClientImpl('apiKey', userToken: token, api: mockApi); + final client = StreamFeedClientImpl('apiKey', api: mockApi); const userId = 'test-user'; From 2d5ce6002c2738f8581f588ece7506bcbeaf8b1d Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 10:02:57 -0400 Subject: [PATCH 03/13] fix error serialization --- .../core/error/stream_feeds_dio_error.dart | 21 +++++++++++++++++++ .../src/core/error/stream_feeds_error.dart | 12 +++++++---- .../lib/src/core/http/stream_http_client.dart | 15 +++++++------ 3 files changed, 38 insertions(+), 10 deletions(-) create mode 100644 packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart diff --git a/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart b/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart new file mode 100644 index 000000000..6d1ad6ac9 --- /dev/null +++ b/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart @@ -0,0 +1,21 @@ +import 'package:dio/dio.dart'; +import 'package:stream_feed/src/core/error/stream_feeds_error.dart'; + +/// Error class specific to StreamFeed and Dio +class StreamFeedsDioError extends DioError { + /// Initialize a stream feed dio error + StreamFeedsDioError({ + required this.error, + required RequestOptions requestOptions, + Response? response, + DioErrorType type = DioErrorType.other, + }) : super( + error: error, + requestOptions: requestOptions, + response: response, + type: type, + ); + + @override + final StreamFeedsNetworkError error; +} \ No newline at end of file diff --git a/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart b/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart index 98db0228d..efc2310e0 100644 --- a/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart +++ b/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:dio/dio.dart'; import 'package:equatable/equatable.dart'; import 'package:stream_feed/src/core/api/responses.dart'; @@ -22,13 +24,14 @@ class StreamFeedsError with EquatableMixin implements Exception { class StreamFeedsNetworkError extends StreamFeedsError { /// Builds a [StreamFeedsNetworkError]. StreamFeedsNetworkError( - FeedsError error, { + FeedsError errorCode, { int? statusCode, this.data, - }) : code = error.code, + }) : code = errorCode.code, statusCode = statusCode ?? data?.statusCode, - super(error.message); + super(errorCode.message); + /// StreamFeedsNetworkError.raw({ required this.code, required String message, @@ -40,7 +43,7 @@ class StreamFeedsNetworkError extends StreamFeedsError { factory StreamFeedsNetworkError.fromDioError(DioError error) { final response = error.response; ErrorResponse? errorResponse; - final data = response?.data; + final data = json.decode(response?.data); if (data != null) { errorResponse = ErrorResponse.fromJson(data); } @@ -67,6 +70,7 @@ class StreamFeedsNetworkError extends StreamFeedsError { /// set stackTrace(StackTrace? stack) => _stackTrace = stack; + /// FeedsError? get errorCode => feedsErrorCodeFromCode(code); /// diff --git a/packages/stream_feed/lib/src/core/http/stream_http_client.dart b/packages/stream_feed/lib/src/core/http/stream_http_client.dart index 1c0c0221c..99a6cae7f 100644 --- a/packages/stream_feed/lib/src/core/http/stream_http_client.dart +++ b/packages/stream_feed/lib/src/core/http/stream_http_client.dart @@ -2,6 +2,7 @@ import 'package:dio/dio.dart' hide Headers; import 'package:logging/logging.dart'; import 'package:meta/meta.dart'; import 'package:stream_feed/src/core/error/feeds_error_code.dart'; +import 'package:stream_feed/src/core/error/stream_feeds_dio_error.dart'; import 'package:stream_feed/src/core/error/stream_feeds_error.dart'; import 'package:stream_feed/src/core/http/interceptor/logging_interceptor.dart'; import 'package:stream_feed/src/core/http/location.dart'; @@ -70,14 +71,16 @@ class StreamHttpClient { @visibleForTesting final Dio httpClient; - StreamFeedsNetworkError _parseError(DioError dioError) { - StreamFeedsNetworkError feedsError; - if (dioError is FeedsError) { - feedsError = dioError.error; + StreamFeedsNetworkError _parseError(DioError err) { + StreamFeedsNetworkError error; + // locally thrown dio error + if (err is StreamFeedsDioError) { + error = err.error; } else { - feedsError = StreamFeedsNetworkError.fromDioError(dioError); + // real network request dio error + error = StreamFeedsNetworkError.fromDioError(err); } - return feedsError..stackTrace = dioError.stackTrace; + return error..stackTrace = err.stackTrace; } /// Combines the base url with the [relativeUrl] From c8ce37aae9b2ce72aa511cffd37f8e567f9e893b Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 10:26:50 -0400 Subject: [PATCH 04/13] fix tests --- example/lib/main.dart | 2 +- packages/stream_feed/example/main.dart | 4 +- .../lib/src/client/stream_feed_client.dart | 1 - .../src/client/stream_feed_client_impl.dart | 4 +- .../core/error/stream_feeds_dio_error.dart | 2 +- .../test/stream_feed_client_test.dart | 190 ++++++++---------- 6 files changed, 88 insertions(+), 115 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index c03c0b3d1..fc56ca17d 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -14,7 +14,7 @@ void main() { final client = StreamFeedClient( _key, - token: const Token(_userToken), + // token: const Token(_userToken), ); runApp( diff --git a/packages/stream_feed/example/main.dart b/packages/stream_feed/example/main.dart index 245c26171..cfe99ea9a 100644 --- a/packages/stream_feed/example/main.dart +++ b/packages/stream_feed/example/main.dart @@ -86,7 +86,7 @@ Future main() async { // Client-side client = StreamFeedClient( apiKey, - token: userToken, + // token: userToken, appId: appId, ); @@ -339,7 +339,7 @@ Future main() async { object: cheeseBurgerRef, )); - client = StreamFeedClient(apiKey, token: frontendToken); + client = StreamFeedClient(apiKey); //token: frontendToken TODO: setUser // ensure the user data is stored on Stream await client.setUser( const User( diff --git a/packages/stream_feed/lib/src/client/stream_feed_client.dart b/packages/stream_feed/lib/src/client/stream_feed_client.dart index 1bff85d44..fc8419342 100644 --- a/packages/stream_feed/lib/src/client/stream_feed_client.dart +++ b/packages/stream_feed/lib/src/client/stream_feed_client.dart @@ -57,7 +57,6 @@ abstract class StreamFeedClient { /// {@endtemplate} factory StreamFeedClient( String apiKey, { - Token? token, String? secret, String? appId, StreamHttpClientOptions? options, diff --git a/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart b/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart index 36f4555f6..d87fc024b 100644 --- a/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart +++ b/packages/stream_feed/lib/src/client/stream_feed_client_impl.dart @@ -144,7 +144,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override BatchOperationsClient get batch { - assert(_ensureCredentials(), ''); + assert(_ensureCredentials(), ''); assert( runner == Runner.server, "You can't use batch operations client side", @@ -175,7 +175,7 @@ class StreamFeedClientImpl implements StreamFeedClient { @override StreamUser user(String userId) { - assert(_ensureCredentials(), ''); + // assert(_ensureCredentials(), ''); return StreamUser(_api.users, userId, userToken: userToken, secret: secret); } diff --git a/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart b/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart index 6d1ad6ac9..3874275e9 100644 --- a/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart +++ b/packages/stream_feed/lib/src/core/error/stream_feeds_dio_error.dart @@ -18,4 +18,4 @@ class StreamFeedsDioError extends DioError { @override final StreamFeedsNetworkError error; -} \ No newline at end of file +} diff --git a/packages/stream_feed/test/stream_feed_client_test.dart b/packages/stream_feed/test/stream_feed_client_test.dart index cdff29683..aa1a677b3 100644 --- a/packages/stream_feed/test/stream_feed_client_test.dart +++ b/packages/stream_feed/test/stream_feed_client_test.dart @@ -9,11 +9,36 @@ import 'mock.dart'; import 'utils.dart'; void main() { + late Map data; + late String userId; + late User user; + late MockAPI mockApi; + late MockUserAPI mockUserAPI; + late Token userToken; group('StreamFeedClientImpl', () { + mockUserAPI = MockUserAPI(); + + data = { + 'name': 'John Doe', + 'occupation': 'Software Engineer', + 'gender': 'male', + }; + userId = 'userId'; + user = User(id: userId, data: data); + userToken = TokenHelper.buildFrontendToken('secret', userId); + + mockApi = MockAPI(); + when(() => mockApi.users).thenReturn(mockUserAPI); + when(() => mockUserAPI.create(userToken, userId, data, getOrCreate: true)) + .thenAnswer((_) async => user); + + when(() => mockUserAPI.get(userToken, userId, withFollowCounts: true)) + .thenAnswer((_) async => user); + group('throw', () { test('throws an AssertionError when no secret or token provided', () { expect( - () => StreamFeedClient('apiKey'), + () => StreamFeedClient('apiKey').collections, throwsA( predicate((e) => e.message == 'At least a secret or userToken must be provided'), @@ -24,14 +49,16 @@ void main() { test( 'throws an AssertionError if token is not provided ' 'while running on client-side', - () { + () async { + final client = StreamFeedClient('apiKey', secret: 'secret'); + expect( - () => StreamFeedClient('apiKey', secret: 'secret'), + () => client.collections, throwsA( predicate( (e) => e.message == - '`userToken` must be provided while running on client-side', + "`userToken` must be provided while running on client-sideplease make sure to call client.setUser", ), ), ); @@ -45,14 +72,14 @@ void main() { expect( () => StreamFeedClient( 'apiKey', - token: TokenHelper.buildFrontendToken('secret', 'userId'), + // token: TokenHelper.buildFrontendToken('secret', 'userId'), runner: Runner.server, - ), + ).collections, throwsA( predicate( (e) => e.message == - '`secret` must be provided while running on server-side', + 'At least a secret or userToken must be provided', ), ), ); @@ -62,13 +89,14 @@ void main() { test( 'throws an AssertionError if secret is provided ' 'while running on client-side', - () { + () async { + final client = + StreamFeedClient('apiKey', secret: 'secret', api: mockApi + // token: TokenHelper.buildFrontendToken('secret', 'userId'), + ); + await client.setUser(user, userToken, extraData: data); expect( - () => StreamFeedClient( - 'apiKey', - secret: 'secret', - token: TokenHelper.buildFrontendToken('secret', 'userId'), - ), + () => client.collections, throwsA( predicate( (e) => @@ -89,7 +117,7 @@ void main() { test("don't throw if token provided while running on client-side", () { StreamFeedClient( 'apiKey', - token: TokenHelper.buildFrontendToken('secret', 'userId'), + // token: TokenHelper.buildFrontendToken('secret', 'userId'), ); }); }); @@ -111,142 +139,88 @@ void main() { }); test('openGraph', () async { - final mockApi = MockAPI(); - final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = StreamFeedClientImpl('apiKey', api: mockApi); - + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); const targetUrl = 'targetUrl'; - when(() => mockApi.openGraph(token, targetUrl)).thenAnswer( + when(() => mockApi.openGraph(userToken, targetUrl)).thenAnswer( (_) async => OpenGraphData.fromJson(jsonFixture('open_graph_data.json')), ); await client.og(targetUrl); - verify(() => mockApi.openGraph(token, targetUrl)).called(1); + verify(() => mockApi.openGraph(userToken, targetUrl)).called(1); }); test('createUser', () async { - final mockApi = MockAPI(); - final mockUserAPI = MockUserAPI(); - when(() => mockApi.users).thenReturn(mockUserAPI); - final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = StreamFeedClientImpl('apiKey', api: mockApi); - - const userId = 'test-user'; - const data = { - 'name': 'John Doe', - 'occupation': 'Software Engineer', - 'gender': 'male', - }; - - when(() => mockUserAPI.create(token, userId, data)).thenAnswer( - (_) async => const User(id: userId, data: data), + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); + + when(() => mockUserAPI.create(userToken, userId, data)).thenAnswer( + (_) async => user, ); - final user = await client.createUser(userId, data); + final newUser = await client.createUser(userId, data); - expect(user.id, userId); - expect(user.data, data); + expect(newUser.id, userId); + expect(newUser.data, data); - verify(() => mockUserAPI.create(token, userId, data)).called(1); + verify(() => mockUserAPI.create(userToken, userId, data)).called(1); }); test('setUser', () async { - final mockApi = MockAPI(); - const id = 'test-user'; - final mockUserAPI = MockUserAPI(); - final token = TokenHelper.buildFrontendToken('secret', id); - - final client = StreamFeedClientImpl('apiKey', api: mockApi); - - const data = { - 'name': 'John Doe', - 'occupation': 'Software Engineer', - 'gender': 'male', - }; - const user = User(id: id, data: data); - when(() => mockApi.users).thenReturn(mockUserAPI); - when(() => mockUserAPI.create(token, id, data, getOrCreate: true)) - .thenAnswer((_) async => user); - - when(() => mockUserAPI.get(token, id, withFollowCounts: true)) - .thenAnswer((_) async => user); - await client.setUser(user, token, extraData: data); - verify(() => mockUserAPI.create(token, id, data, getOrCreate: true)) + final client = StreamFeedClient('apiKey', api: mockApi); + + await client.setUser(user, userToken, extraData: data); + verify(() => + mockUserAPI.create(userToken, userId, data, getOrCreate: true)) .called(1); - verify(() => mockUserAPI.get(token, id, withFollowCounts: true)) + verify(() => mockUserAPI.get(userToken, userId, withFollowCounts: true)) .called(1); }); test('getUser', () async { - final mockApi = MockAPI(); - final mockUserAPI = MockUserAPI(); - when(() => mockApi.users).thenReturn(mockUserAPI); - final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = StreamFeedClientImpl('apiKey', api: mockApi); - - const userId = 'test-user'; - const data = { - 'name': 'John Doe', - 'occupation': 'Software Engineer', - 'gender': 'male', - }; - - when(() => mockUserAPI.get(token, userId)).thenAnswer( - (_) async => const User(id: userId, data: data), + final client = StreamFeedClient('apiKey', api: mockApi); + + await client.setUser(user, userToken, extraData: data); + when(() => mockUserAPI.get(userToken, userId)).thenAnswer( + (_) async => user, ); - final user = await client.getUser(userId); + final newUser = await client.getUser(userId); - expect(user.id, userId); - expect(user.data, data); + expect(newUser.id, userId); + expect(newUser.data, data); - verify(() => mockUserAPI.get(token, userId)).called(1); + verify(() => mockUserAPI.get(userToken, userId)).called(1); }); test('updateUser', () async { - final mockApi = MockAPI(); - final mockUserAPI = MockUserAPI(); - when(() => mockApi.users).thenReturn(mockUserAPI); - final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = StreamFeedClientImpl('apiKey', api: mockApi); - - const userId = 'test-user'; - const data = { - 'name': 'John Doe', - 'occupation': 'Software Engineer', - 'gender': 'male', - }; - - when(() => mockUserAPI.update(token, userId, data)).thenAnswer( - (_) async => const User(id: userId, data: data), + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); + when(() => mockUserAPI.update(userToken, userId, data)).thenAnswer( + (_) async => user, ); - final user = await client.updateUser(userId, data); + final newUser = await client.updateUser(userId, data); - expect(user.id, userId); - expect(user.data, data); + expect(newUser.id, userId); + expect(newUser.data, data); - verify(() => mockUserAPI.update(token, userId, data)).called(1); + verify(() => mockUserAPI.update(userToken, userId, data)).called(1); }); test('delete', () async { - final mockApi = MockAPI(); - final mockUserAPI = MockUserAPI(); - when(() => mockApi.users).thenReturn(mockUserAPI); - final token = TokenHelper.buildFrontendToken('secret', 'userId'); - final client = StreamFeedClientImpl('apiKey', api: mockApi); - - const userId = 'test-user'; + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); - when(() => mockUserAPI.delete(token, userId)).thenAnswer( + when(() => mockUserAPI.delete(userToken, userId)).thenAnswer( (_) async => Future.value(), ); await client.deleteUser(userId); - verify(() => mockUserAPI.delete(token, userId)).called(1); + verify(() => mockUserAPI.delete(userToken, userId)).called(1); }); }); } From 2919ea61c1369dc78bee402ca0ae41d662113f81 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 10:45:03 -0400 Subject: [PATCH 05/13] fix analyzer --- packages/stream_feed_flutter_core/example/lib/main.dart | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/packages/stream_feed_flutter_core/example/lib/main.dart b/packages/stream_feed_flutter_core/example/lib/main.dart index e1f073893..6198668fd 100644 --- a/packages/stream_feed_flutter_core/example/lib/main.dart +++ b/packages/stream_feed_flutter_core/example/lib/main.dart @@ -5,10 +5,7 @@ import 'package:stream_feed_flutter_core/stream_feed_flutter_core.dart'; Future main() async { const apiKey = String.fromEnvironment('key'); const userToken = String.fromEnvironment('user_token'); - final client = StreamFeedClient( - apiKey, - token: const Token(userToken), - ); + final client = StreamFeedClient(apiKey); await client.setUser( const User( From ac60e510d7c98c0f55e2a4e05c9cea005b149c65 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 11:28:34 -0400 Subject: [PATCH 06/13] fix flutter example + fix build --- .../example/ios/.gitignore | 1 + .../example/ios/Flutter/Debug.xcconfig | 2 + .../example/ios/Flutter/Release.xcconfig | 2 + .../stream_feed_flutter/example/ios/Podfile | 3 + .../ios/Runner.xcodeproj/project.pbxproj | 539 ++++++++++++++++++ .../contents.xcworkspacedata | 10 + .../example/ios/Runner/Info.plist | 45 ++ .../stream_feed_flutter/example/lib/main.dart | 6 +- .../macos/Flutter/Flutter-Debug.xcconfig | 2 + .../macos/Flutter/Flutter-Release.xcconfig | 2 + .../stream_feed_flutter_core/pubspec.yaml | 4 +- 11 files changed, 610 insertions(+), 6 deletions(-) create mode 100644 packages/stream_feed_flutter/example/ios/Flutter/Debug.xcconfig create mode 100644 packages/stream_feed_flutter/example/ios/Flutter/Release.xcconfig create mode 100644 packages/stream_feed_flutter/example/ios/Runner.xcodeproj/project.pbxproj create mode 100644 packages/stream_feed_flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata create mode 100644 packages/stream_feed_flutter/example/ios/Runner/Info.plist create mode 100644 packages/stream_feed_flutter/example/macos/Flutter/Flutter-Debug.xcconfig create mode 100644 packages/stream_feed_flutter/example/macos/Flutter/Flutter-Release.xcconfig diff --git a/packages/stream_feed_flutter/example/ios/.gitignore b/packages/stream_feed_flutter/example/ios/.gitignore index 151026b91..7a7f9873a 100644 --- a/packages/stream_feed_flutter/example/ios/.gitignore +++ b/packages/stream_feed_flutter/example/ios/.gitignore @@ -1,3 +1,4 @@ +**/dgph *.mode1v3 *.mode2v3 *.moved-aside diff --git a/packages/stream_feed_flutter/example/ios/Flutter/Debug.xcconfig b/packages/stream_feed_flutter/example/ios/Flutter/Debug.xcconfig new file mode 100644 index 000000000..ec97fc6f3 --- /dev/null +++ b/packages/stream_feed_flutter/example/ios/Flutter/Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/stream_feed_flutter/example/ios/Flutter/Release.xcconfig b/packages/stream_feed_flutter/example/ios/Flutter/Release.xcconfig new file mode 100644 index 000000000..c4855bfe2 --- /dev/null +++ b/packages/stream_feed_flutter/example/ios/Flutter/Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "Generated.xcconfig" diff --git a/packages/stream_feed_flutter/example/ios/Podfile b/packages/stream_feed_flutter/example/ios/Podfile index f7d6a5e68..1e8c3c90a 100644 --- a/packages/stream_feed_flutter/example/ios/Podfile +++ b/packages/stream_feed_flutter/example/ios/Podfile @@ -28,6 +28,9 @@ require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelpe flutter_ios_podfile_setup target 'Runner' do + use_frameworks! + use_modular_headers! + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) end diff --git a/packages/stream_feed_flutter/example/ios/Runner.xcodeproj/project.pbxproj b/packages/stream_feed_flutter/example/ios/Runner.xcodeproj/project.pbxproj new file mode 100644 index 000000000..d37754f46 --- /dev/null +++ b/packages/stream_feed_flutter/example/ios/Runner.xcodeproj/project.pbxproj @@ -0,0 +1,539 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; + FECAB257DD31DF066C59C9BE /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7BA38C418B9AC2371B53D14F /* Pods_Runner.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXCopyFilesBuildPhase section */ + 9705A1C41CF9048500538489 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXCopyFilesBuildPhase section */ + +/* Begin PBXFileReference section */ + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; + 1C563062D447081032A6CFF1 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; + 4E537F10D993948B075EADC8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; + 60EAC7CBAFBCC1CFD59B34F8 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; + 7BA38C418B9AC2371B53D14F /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 97C146EB1CF9000F007C117D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + FECAB257DD31DF066C59C9BE /* Pods_Runner.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6E70F772BA15B7DE02FFDE33 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 7BA38C418B9AC2371B53D14F /* Pods_Runner.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; + 8C2599A201787CBFAC2BC4F2 /* Pods */ = { + isa = PBXGroup; + children = ( + 4E537F10D993948B075EADC8 /* Pods-Runner.debug.xcconfig */, + 1C563062D447081032A6CFF1 /* Pods-Runner.release.xcconfig */, + 60EAC7CBAFBCC1CFD59B34F8 /* Pods-Runner.profile.xcconfig */, + ); + name = Pods; + path = Pods; + sourceTree = ""; + }; + 9740EEB11CF90186004384FC /* Flutter */ = { + isa = PBXGroup; + children = ( + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, + 9740EEB21CF90195004384FC /* Debug.xcconfig */, + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, + 9740EEB31CF90195004384FC /* Generated.xcconfig */, + ); + name = Flutter; + sourceTree = ""; + }; + 97C146E51CF9000F007C117D = { + isa = PBXGroup; + children = ( + 9740EEB11CF90186004384FC /* Flutter */, + 97C146F01CF9000F007C117D /* Runner */, + 97C146EF1CF9000F007C117D /* Products */, + 8C2599A201787CBFAC2BC4F2 /* Pods */, + 6E70F772BA15B7DE02FFDE33 /* Frameworks */, + ); + sourceTree = ""; + }; + 97C146EF1CF9000F007C117D /* Products */ = { + isa = PBXGroup; + children = ( + 97C146EE1CF9000F007C117D /* Runner.app */, + ); + name = Products; + sourceTree = ""; + }; + 97C146F01CF9000F007C117D /* Runner */ = { + isa = PBXGroup; + children = ( + 97C146FA1CF9000F007C117D /* Main.storyboard */, + 97C146FD1CF9000F007C117D /* Assets.xcassets */, + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, + 97C147021CF9000F007C117D /* Info.plist */, + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, + ); + path = Runner; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 97C146ED1CF9000F007C117D /* Runner */ = { + isa = PBXNativeTarget; + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; + buildPhases = ( + 4A30BBE2D18D2F28CB67DA04 /* [CP] Check Pods Manifest.lock */, + 9740EEB61CF901F6004384FC /* Run Script */, + 97C146EA1CF9000F007C117D /* Sources */, + 97C146EB1CF9000F007C117D /* Frameworks */, + 97C146EC1CF9000F007C117D /* Resources */, + 9705A1C41CF9048500538489 /* Embed Frameworks */, + 3B06AD1E1E4923F5004D2608 /* Thin Binary */, + ACB67128DF8A0EB720ECE4EF /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = Runner; + productName = Runner; + productReference = 97C146EE1CF9000F007C117D /* Runner.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 97C146E61CF9000F007C117D /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 1020; + ORGANIZATIONNAME = ""; + TargetAttributes = { + 97C146ED1CF9000F007C117D = { + CreatedOnToolsVersion = 7.3.1; + LastSwiftMigration = 1100; + }; + }; + }; + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 97C146E51CF9000F007C117D; + productRefGroup = 97C146EF1CF9000F007C117D /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 97C146ED1CF9000F007C117D /* Runner */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 97C146EC1CF9000F007C117D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Thin Binary"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; + }; + 4A30BBE2D18D2F28CB67DA04 /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 9740EEB61CF901F6004384FC /* Run Script */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Run Script"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; + }; + ACB67128DF8A0EB720ECE4EF /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 97C146EA1CF9000F007C117D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXVariantGroup section */ + 97C146FA1CF9000F007C117D /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C146FB1CF9000F007C117D /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 97C147001CF9000F007C117D /* Base */, + ); + name = LaunchScreen.storyboard; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 249021D3217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Profile; + }; + 249021D4217E4FDB00AE95B9 /* Profile */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Profile; + }; + 97C147031CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 97C147041CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 97C147061CF9000F007C117D /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Debug; + }; + 97C147071CF9000F007C117D /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; + ENABLE_BITCODE = NO; + INFOPLIST_FILE = Runner/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.example.example; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; + SWIFT_VERSION = 5.0; + VERSIONING_SYSTEM = "apple-generic"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147031CF9000F007C117D /* Debug */, + 97C147041CF9000F007C117D /* Release */, + 249021D3217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 97C147061CF9000F007C117D /* Debug */, + 97C147071CF9000F007C117D /* Release */, + 249021D4217E4FDB00AE95B9 /* Profile */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 97C146E61CF9000F007C117D /* Project object */; +} diff --git a/packages/stream_feed_flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata b/packages/stream_feed_flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata new file mode 100644 index 000000000..21a3cc14c --- /dev/null +++ b/packages/stream_feed_flutter/example/ios/Runner.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/packages/stream_feed_flutter/example/ios/Runner/Info.plist b/packages/stream_feed_flutter/example/ios/Runner/Info.plist new file mode 100644 index 000000000..a060db61e --- /dev/null +++ b/packages/stream_feed_flutter/example/ios/Runner/Info.plist @@ -0,0 +1,45 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + example + CFBundlePackageType + APPL + CFBundleShortVersionString + $(FLUTTER_BUILD_NAME) + CFBundleSignature + ???? + CFBundleVersion + $(FLUTTER_BUILD_NUMBER) + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UIViewControllerBasedStatusBarAppearance + + + diff --git a/packages/stream_feed_flutter/example/lib/main.dart b/packages/stream_feed_flutter/example/lib/main.dart index b9643cc0b..c7741cd5f 100644 --- a/packages/stream_feed_flutter/example/lib/main.dart +++ b/packages/stream_feed_flutter/example/lib/main.dart @@ -81,11 +81,7 @@ mixin StreamFeedMixin on State { /// 3. Play around with the app! void main() { const apiKey = String.fromEnvironment('key'); - const userToken = String.fromEnvironment('user_token'); - final client = StreamFeedClient( - apiKey, - token: const Token(userToken), - ); + final client = StreamFeedClient(apiKey); runApp( MobileApp( diff --git a/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Debug.xcconfig b/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Debug.xcconfig new file mode 100644 index 000000000..4b81f9b2d --- /dev/null +++ b/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Debug.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Release.xcconfig b/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Release.xcconfig new file mode 100644 index 000000000..5caa9d157 --- /dev/null +++ b/packages/stream_feed_flutter/example/macos/Flutter/Flutter-Release.xcconfig @@ -0,0 +1,2 @@ +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" +#include "ephemeral/Flutter-Generated.xcconfig" diff --git a/packages/stream_feed_flutter_core/pubspec.yaml b/packages/stream_feed_flutter_core/pubspec.yaml index 3b34b2520..3ac1ff9e4 100644 --- a/packages/stream_feed_flutter_core/pubspec.yaml +++ b/packages/stream_feed_flutter_core/pubspec.yaml @@ -14,7 +14,9 @@ dependencies: flutter: sdk: flutter rxdart: ^0.27.1 - stream_feed: ^0.4.0+3 + stream_feed: + path: ../stream_feed + # stream_feed: ^0.4.0+3 dev_dependencies: flutter_test: From fdac670e538c95bee17732cdaa473d115c4380ac Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 15:59:06 -0400 Subject: [PATCH 07/13] fix test --- .../test/stream_feed_client_test.dart | 154 +++++++++--------- .../test/stream_feeds_error_test.dart | 2 +- 2 files changed, 75 insertions(+), 81 deletions(-) diff --git a/packages/stream_feed/test/stream_feed_client_test.dart b/packages/stream_feed/test/stream_feed_client_test.dart index aa1a677b3..c6673995e 100644 --- a/packages/stream_feed/test/stream_feed_client_test.dart +++ b/packages/stream_feed/test/stream_feed_client_test.dart @@ -35,6 +35,78 @@ void main() { when(() => mockUserAPI.get(userToken, userId, withFollowCounts: true)) .thenAnswer((_) async => user); + test('setUser', () async { + final client = StreamFeedClient('apiKey', api: mockApi); + + await client.setUser(user, userToken, extraData: data); + verify(() => + mockUserAPI.create(userToken, userId, data, getOrCreate: true)) + .called(1); + + verify(() => mockUserAPI.get(userToken, userId, withFollowCounts: true)) + .called(1); + }); + + test('createUser', () async { + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); + + when(() => mockUserAPI.create(userToken, userId, data)).thenAnswer( + (_) async => user, + ); + + final newUser = await client.createUser(userId, data); + + expect(newUser.id, userId); + expect(newUser.data, data); + + verify(() => mockUserAPI.create(userToken, userId, data)).called(1); + }); + + test('getUser', () async { + final client = StreamFeedClient('apiKey', api: mockApi); + + await client.setUser(user, userToken, extraData: data); + when(() => mockUserAPI.get(userToken, userId)).thenAnswer( + (_) async => user, + ); + + final newUser = await client.getUser(userId); + + expect(newUser.id, userId); + expect(newUser.data, data); + + verify(() => mockUserAPI.get(userToken, userId)).called(1); + }); + + test('updateUser', () async { + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); + when(() => mockUserAPI.update(userToken, userId, data)).thenAnswer( + (_) async => user, + ); + + final newUser = await client.updateUser(userId, data); + + expect(newUser.id, userId); + expect(newUser.data, data); + + verify(() => mockUserAPI.update(userToken, userId, data)).called(1); + }); + + test('delete', () async { + final client = StreamFeedClient('apiKey', api: mockApi); + await client.setUser(user, userToken, extraData: data); + + when(() => mockUserAPI.delete(userToken, userId)).thenAnswer( + (_) async => Future.value(), + ); + + await client.deleteUser(userId); + + verify(() => mockUserAPI.delete(userToken, userId)).called(1); + }); + group('throw', () { test('throws an AssertionError when no secret or token provided', () { expect( @@ -72,7 +144,6 @@ void main() { expect( () => StreamFeedClient( 'apiKey', - // token: TokenHelper.buildFrontendToken('secret', 'userId'), runner: Runner.server, ).collections, throwsA( @@ -91,9 +162,7 @@ void main() { 'while running on client-side', () async { final client = - StreamFeedClient('apiKey', secret: 'secret', api: mockApi - // token: TokenHelper.buildFrontendToken('secret', 'userId'), - ); + StreamFeedClient('apiKey', secret: 'secret', api: mockApi); await client.setUser(user, userToken, extraData: data); expect( () => client.collections, @@ -115,10 +184,7 @@ void main() { }); test("don't throw if token provided while running on client-side", () { - StreamFeedClient( - 'apiKey', - // token: TokenHelper.buildFrontendToken('secret', 'userId'), - ); + StreamFeedClient('apiKey'); }); }); test('getters', () async { @@ -150,77 +216,5 @@ void main() { await client.og(targetUrl); verify(() => mockApi.openGraph(userToken, targetUrl)).called(1); }); - - test('createUser', () async { - final client = StreamFeedClient('apiKey', api: mockApi); - await client.setUser(user, userToken, extraData: data); - - when(() => mockUserAPI.create(userToken, userId, data)).thenAnswer( - (_) async => user, - ); - - final newUser = await client.createUser(userId, data); - - expect(newUser.id, userId); - expect(newUser.data, data); - - verify(() => mockUserAPI.create(userToken, userId, data)).called(1); - }); - - test('setUser', () async { - final client = StreamFeedClient('apiKey', api: mockApi); - - await client.setUser(user, userToken, extraData: data); - verify(() => - mockUserAPI.create(userToken, userId, data, getOrCreate: true)) - .called(1); - - verify(() => mockUserAPI.get(userToken, userId, withFollowCounts: true)) - .called(1); - }); - - test('getUser', () async { - final client = StreamFeedClient('apiKey', api: mockApi); - - await client.setUser(user, userToken, extraData: data); - when(() => mockUserAPI.get(userToken, userId)).thenAnswer( - (_) async => user, - ); - - final newUser = await client.getUser(userId); - - expect(newUser.id, userId); - expect(newUser.data, data); - - verify(() => mockUserAPI.get(userToken, userId)).called(1); - }); - - test('updateUser', () async { - final client = StreamFeedClient('apiKey', api: mockApi); - await client.setUser(user, userToken, extraData: data); - when(() => mockUserAPI.update(userToken, userId, data)).thenAnswer( - (_) async => user, - ); - - final newUser = await client.updateUser(userId, data); - - expect(newUser.id, userId); - expect(newUser.data, data); - - verify(() => mockUserAPI.update(userToken, userId, data)).called(1); - }); - - test('delete', () async { - final client = StreamFeedClient('apiKey', api: mockApi); - await client.setUser(user, userToken, extraData: data); - - when(() => mockUserAPI.delete(userToken, userId)).thenAnswer( - (_) async => Future.value(), - ); - - await client.deleteUser(userId); - - verify(() => mockUserAPI.delete(userToken, userId)).called(1); - }); }); } diff --git a/packages/stream_feed/test/stream_feeds_error_test.dart b/packages/stream_feed/test/stream_feeds_error_test.dart index ffdd275ca..78014dd4f 100644 --- a/packages/stream_feed/test/stream_feeds_error_test.dart +++ b/packages/stream_feed/test/stream_feeds_error_test.dart @@ -31,7 +31,7 @@ void main() { response: Response( requestOptions: options, statusCode: data.statusCode, - data: data.toJson(), + data: "${data.toJson()}", ), ); final error = StreamFeedsNetworkError.fromDioError(dioError); From 6e448c79f20918756369785d2320cf037e67aecb Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 16:06:02 -0400 Subject: [PATCH 08/13] fix test: StreamFeedNetworkError .fromDioError --- packages/stream_feed/test/stream_feeds_error_test.dart | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/stream_feed/test/stream_feeds_error_test.dart b/packages/stream_feed/test/stream_feeds_error_test.dart index 78014dd4f..e900a514e 100644 --- a/packages/stream_feed/test/stream_feeds_error_test.dart +++ b/packages/stream_feed/test/stream_feeds_error_test.dart @@ -1,3 +1,5 @@ +import 'dart:convert'; + import 'package:dio/dio.dart'; import 'package:stream_feed/src/core/api/responses.dart'; import 'package:stream_feed/src/core/error/feeds_error_code.dart'; @@ -31,7 +33,7 @@ void main() { response: Response( requestOptions: options, statusCode: data.statusCode, - data: "${data.toJson()}", + data: json.encode(data.toJson()), ), ); final error = StreamFeedsNetworkError.fromDioError(dioError); From bc7aef25d958904bd6303359c5b53e10ce4a9ec0 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 16:18:50 -0400 Subject: [PATCH 09/13] update changelog + cleanup comments --- example/lib/main.dart | 5 +---- packages/stream_feed/CHANGELOG.md | 20 ++++++++++++++++++++ packages/stream_feed/example/main.dart | 3 +-- 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index fc56ca17d..bcd5ea751 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -12,10 +12,7 @@ void main() { const _key = String.fromEnvironment('key'); const _userToken = String.fromEnvironment('user_token'); - final client = StreamFeedClient( - _key, - // token: const Token(_userToken), - ); + final client = StreamFeedClient(_key); runApp( MyApp( diff --git a/packages/stream_feed/CHANGELOG.md b/packages/stream_feed/CHANGELOG.md index 4c4d7ff30..024700311 100644 --- a/packages/stream_feed/CHANGELOG.md +++ b/packages/stream_feed/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.5.0: 12/01/2022 + +- BREAKING: we no longer accept a token in the constructor. This change is inspired by Stream Chat, and allows for use cases like multi account management. It allows to instantiate `StreamFeedClient` at the top of your widget tree for example, and connecting the user later. + +```diff +- client = StreamFeedClient(apiKey, token: frontendToken); ++ client = StreamFeedClient(apiKey); ++ ++ await client.setUser( ++ const User( ++ data: { ++ 'name': 'John Doe', ++ 'occupation': 'Software Engineer', ++ 'gender': 'male' ++ }, ++ ), ++ frontendToken, ++ ); +``` + ## 0.4.0+3: 27/12/2021 - fix: call profile in setUser, so that currentUser data is not null diff --git a/packages/stream_feed/example/main.dart b/packages/stream_feed/example/main.dart index cfe99ea9a..62ed0d6ae 100644 --- a/packages/stream_feed/example/main.dart +++ b/packages/stream_feed/example/main.dart @@ -86,7 +86,6 @@ Future main() async { // Client-side client = StreamFeedClient( apiKey, - // token: userToken, appId: appId, ); @@ -339,7 +338,7 @@ Future main() async { object: cheeseBurgerRef, )); - client = StreamFeedClient(apiKey); //token: frontendToken TODO: setUser + client = StreamFeedClient(apiKey); // ensure the user data is stored on Stream await client.setUser( const User( From 7347f6db17b3927209908ffa55825425faf8d9c7 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Tue, 11 Jan 2022 16:23:13 -0400 Subject: [PATCH 10/13] update READMEs --- packages/stream_feed/README.md | 6 ++++-- packages/stream_feed_flutter_core/README.md | 17 ++++++++++++++--- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/packages/stream_feed/README.md b/packages/stream_feed/README.md index 7b0f4bdcc..995de66a5 100644 --- a/packages/stream_feed/README.md +++ b/packages/stream_feed/README.md @@ -66,8 +66,10 @@ final userToken = client.frontendToken('the-user-id'); #### Client API init ```dart -// Instantiate new client with a user token -var client = StreamFeedClient(apiKey, token: Token('userToken')); +// Instantiate new client and set the user token +var client = StreamFeedClient(apiKey); + +await client.setUser(user:user, token: frontendToken); ``` ### 🔮 Examples diff --git a/packages/stream_feed_flutter_core/README.md b/packages/stream_feed_flutter_core/README.md index c5b7d56f6..a03dbec8e 100644 --- a/packages/stream_feed_flutter_core/README.md +++ b/packages/stream_feed_flutter_core/README.md @@ -45,9 +45,20 @@ import 'package:stream_feed_flutter_core/stream_feed_flutter_core.dart'; void main() { const apiKey = 'API-KEY'; const userToken = 'USER-TOKEN'; - final client = StreamFeedClient( - apiKey, - token: const Token(userToken), + final client = StreamFeedClient(apiKey); + + await client.setUser( + const User( + id: 'GroovinChip', + data: { + 'handle': '@GroovinChip', + 'first_name': 'Reuben', + 'last_name': 'Turner', + 'full_name': 'Reuben Turner', + 'profile_image': 'https://avatars.githubusercontent.com/u/4250470?v=4', + }, + ), + const Token(userToken), ); runApp( From 0da3234bbe391dd925a9e24346b0a32252cae626 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Wed, 12 Jan 2022 09:31:30 -0400 Subject: [PATCH 11/13] apply code reviews --- packages/stream_feed/lib/src/client/stream_feed_client.dart | 1 - .../stream_feed/lib/src/core/error/stream_feeds_error.dart | 4 ---- 2 files changed, 5 deletions(-) diff --git a/packages/stream_feed/lib/src/client/stream_feed_client.dart b/packages/stream_feed/lib/src/client/stream_feed_client.dart index fc8419342..dae97ad0e 100644 --- a/packages/stream_feed/lib/src/client/stream_feed_client.dart +++ b/packages/stream_feed/lib/src/client/stream_feed_client.dart @@ -68,7 +68,6 @@ abstract class StreamFeedClient { }) => StreamFeedClientImpl( apiKey, - // userToken: token, secret: secret, appId: appId, options: options, diff --git a/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart b/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart index efc2310e0..8fa64e6e8 100644 --- a/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart +++ b/packages/stream_feed/lib/src/core/error/stream_feeds_error.dart @@ -31,7 +31,6 @@ class StreamFeedsNetworkError extends StreamFeedsError { statusCode = statusCode ?? data?.statusCode, super(errorCode.message); - /// StreamFeedsNetworkError.raw({ required this.code, required String message, @@ -67,13 +66,10 @@ class StreamFeedsNetworkError extends StreamFeedsError { StackTrace? _stackTrace; - /// set stackTrace(StackTrace? stack) => _stackTrace = stack; - /// FeedsError? get errorCode => feedsErrorCodeFromCode(code); - /// bool get isRetriable => data == null; @override From 356489e40de534a21284324c2345fd5bb5d0ef34 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Wed, 12 Jan 2022 10:12:19 -0400 Subject: [PATCH 12/13] llc: prepare for release --- packages/stream_feed/lib/version.dart | 2 +- packages/stream_feed/pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/stream_feed/lib/version.dart b/packages/stream_feed/lib/version.dart index 155d7346a..a49655a0a 100644 --- a/packages/stream_feed/lib/version.dart +++ b/packages/stream_feed/lib/version.dart @@ -1,3 +1,3 @@ /// Current package version /// Used in [HttpClient] to build the `x-stream-client` header -const String packageVersion = '0.4.0+3'; +const String packageVersion = '0.5.0'; diff --git a/packages/stream_feed/pubspec.yaml b/packages/stream_feed/pubspec.yaml index 40096b518..5e2280a02 100644 --- a/packages/stream_feed/pubspec.yaml +++ b/packages/stream_feed/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_feed description: Stream Feed official Dart SDK. Build your own feed experience using Dart and Flutter. -version: 0.4.0+3 +version: 0.5.0 repository: https://github.com/GetStream/stream-feed-flutter issue_tracker: https://github.com/GetStream/stream-feed-flutter/issues homepage: https://getstream.io/ From 49a213316d9c7149d80da1e289357c7cb97b8388 Mon Sep 17 00:00:00 2001 From: Sacha Arbonel Date: Wed, 12 Jan 2022 10:32:14 -0400 Subject: [PATCH 13/13] prepare for release --- .../stream_feed_flutter_core/CHANGELOG.md | 20 +++++++++++++++++++ .../stream_feed_flutter_core/pubspec.yaml | 6 ++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/packages/stream_feed_flutter_core/CHANGELOG.md b/packages/stream_feed_flutter_core/CHANGELOG.md index 5ee4c4ccc..98eaed326 100644 --- a/packages/stream_feed_flutter_core/CHANGELOG.md +++ b/packages/stream_feed_flutter_core/CHANGELOG.md @@ -1,3 +1,23 @@ +## 0.6.0: 12/01/2022 + +- BREAKING: bumped llc to 0.5.0, which is a breaking change. We no longer accept a token in the constructor. This change is inspired by Stream Chat, and allows for use cases like multi account management. It allows to instantiate `StreamFeedClient` at the top of your widget tree for example, and connecting the user later. + +```diff +- client = StreamFeedClient(apiKey, token: frontendToken); ++ client = StreamFeedClient(apiKey); ++ ++ await client.setUser( ++ const User( ++ data: { ++ 'name': 'John Doe', ++ 'occupation': 'Software Engineer', ++ 'gender': 'male' ++ }, ++ ), ++ frontendToken, ++ ); +``` + ## 0.5.0: 27/12/2021 - fix: the convenient typedefs on generic classes we provided was breaking autocomplete diff --git a/packages/stream_feed_flutter_core/pubspec.yaml b/packages/stream_feed_flutter_core/pubspec.yaml index 3ac1ff9e4..b2cecf9c6 100644 --- a/packages/stream_feed_flutter_core/pubspec.yaml +++ b/packages/stream_feed_flutter_core/pubspec.yaml @@ -1,6 +1,6 @@ name: stream_feed_flutter_core description: Stream Feed official Flutter SDK Core. Build your own feed experience using Dart and Flutter. -version: 0.5.0 +version: 0.6.0 repository: https://github.com/GetStream/stream-feed-flutter issue_tracker: https://github.com/GetStream/stream-feed-flutter/issues homepage: https://getstream.io/ @@ -14,9 +14,7 @@ dependencies: flutter: sdk: flutter rxdart: ^0.27.1 - stream_feed: - path: ../stream_feed - # stream_feed: ^0.4.0+3 + stream_feed: ^0.5.0 dev_dependencies: flutter_test: