Testing with the fake server
package:crm_sdk/testing.dart has a fake PurrCRM for your tests and demo builds. It is pure Dart and reads no files.
FakeCrmServeranswers every route the package uses, in memory, the way PurrCRM does: parts switched off answer 404, a conversation that is not the user’s is not found, ratings are given once, surveys check their answers, events are kept once. Each new user finds three conversations (one with an unread reply), a ticket in progress, a help center of five articles, and one in-app message of each kind, under the product name you give it.FakeCrmClient(server)is anhttp.Clientover it: hand it toCrmConfig.httpClient, withapiBase: FakeCrmClient.base. Setofflineto fail every request, andlatencyto slow them;requestskeeps what was asked.StandaloneCrmHostis the server’s world when you have no fake platform of your own: any bearer token is a user, every part is on, and what PurrCRM would push is kept innotices.- What your team does:
server.staffReply(conversationId, text),server.closeConversation(id),server.sendTest(MessageKind.banner); andhelpBot,staffReplyAfterandmessengerWaitForto change how it answers.conversationsOf(userId),articleRatings,eventsandexportOf(userId)say what happened.
A widget test
Section titled “A widget test”testWidgets('the badge counts the reply waiting', (tester) async { final server = FakeCrmServer(productName: 'Northwind')..staffReplyAfter = null; final crm = Crm( config: CrmConfig( apiBase: FakeCrmClient.base, appKey: server.appKey, appVersion: '1.0.0', productName: 'Northwind', httpClient: FakeCrmClient(server), followLifecycle: false, flushEvery: Duration.zero, store: MemoryCrmStore(prefix: 'test'), ), // OneUser: a CrmTokens of the test's that answers 'user-1'. auth: const CrmAuth.tokens(OneUser('user-1')), ) ..session(const CrmSession(guestId: 'user-1')) ..setReady(true); // The app's public face (its parts) is read as the facade starts. await tester.runAsync(crm.start); await tester.pumpWidget(CrmScope(crm: crm, child: const MyApp())); await tester.pump(const Duration(milliseconds: 100)); expect(find.text('1'), findsOneWidget);
// Let go of everything inside the test body: a facade disposed in a // tearDown runs outside the test's fake clock, and hangs. await tester.pumpWidget(const SizedBox.shrink()); server.close(); await crm.dispose(); await tester.pump(const Duration(seconds: 1));});Make the facade inside the test body too, for the same reason. A page transition takes most of a second in a widget test: pump through it before looking.
Your own fake platform
Section titled “Your own fake platform”If your tests already fake your own backend, make the server over it with your own FakeCrmHost (the clock, which parts are on, who a token is, whether a user turned events off, and what becomes of a notice), and hand it each request your fake receives for PurrCRM (handle, or hold then answer).
A demo build
Section titled “A demo build”Run your app over the fake for a demo or a screenshot build: hand FakeCrmClient(FakeCrmServer()) to CrmConfig.httpClient, and any name signs in. The package’s example/ app does this by default:
cd exampleflutter run # over the fakeflutter run --dart-define=CRM_API_BASE=https://app.purrcrm.com \ --dart-define=CRM_APP_KEY=app_... # against your PurrCRMSee the testing reference for every class.