From f8df35e60c9d020b7e3b893ee0e38d4016f20061 Mon Sep 17 00:00:00 2001 From: miaolu <miaomiao.lu@highsoft.ltd> Date: Fri, 23 Dec 2022 06:36:26 +0000 Subject: [PATCH] =?UTF-8?q?fix:=20#247=20=E5=88=9B=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=E9=A2=98=E9=A1=B5=E9=9D=A2=E6=A0=B7=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- assets/images/create_issuue_add_icon.png | Bin 0 -> 278 bytes assets/images/photo_icon.png | Bin 0 -> 1723 bytes lib/core/widgets/input_field_with_title.dart | 2 +- lib/core/widgets/markdown_input_box.dart | 25 ++----- lib/domain/description_content.dart | 16 +++++ lib/domain/issue_detail.dart | 8 +-- lib/domain/note.dart | 6 +- lib/modules/issues/issue_creation_page.dart | 52 +++++++------- lib/modules/issues/issue_creation_view.dart | 66 ++++-------------- lib/modules/issues/selectable.dart | 4 +- test/domain/description_content_test.dart | 28 ++++++++ .../create_issue_in_sub_group_test.dart | 11 ++- .../issues/issue_creation_page_test.dart | 12 ++-- 13 files changed, 112 insertions(+), 118 deletions(-) create mode 100644 assets/images/create_issuue_add_icon.png create mode 100644 assets/images/photo_icon.png create mode 100644 lib/domain/description_content.dart create mode 100644 test/domain/description_content_test.dart diff --git a/assets/images/create_issuue_add_icon.png b/assets/images/create_issuue_add_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..4e8b2574f760955b1b89e487428582beb82496c7 GIT binary patch literal 278 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDB3?!H8JlO)`1o(uw8XKD!8XD{C8_3AW%E(BI zii!yc2=egova_?Zu&@ACb#+Z_Z}0Eu=xcB90V2Uq6M2B5{3Stt!9W@YR2}lCF1pBg z8^~|-ba4!+xRo4pl!3W^`w?4_ga$@2Hj5McPUi<6Vqo^+;I(I!$hJ?I_~ZGB0}2g# zjSP#0nnRj4-U($mW|FkycOxUyzxT-(e)o&oq}}L`ePr%uT_APz(N6K*Pj!yHzvp;k z|MdK{in<s^t;H4=%!MIL{VbR3*xLA+B2;GFwEvUu=3($iYZ}8Rzl?t(Yws=vxzN+q K&t;ucLK6U*nOczm literal 0 HcmV?d00001 diff --git a/assets/images/photo_icon.png b/assets/images/photo_icon.png new file mode 100644 index 0000000000000000000000000000000000000000..46e3b178a24cf9bd4e51e514c36fddf6cf49131f GIT binary patch literal 1723 zcmcIji$BwA7~jTn9mX)sow*#&+!=De4b#x+Q>2x!P#u?!Ivq|5ZL`^GVMl04D%XUN z`joUpCAlQGNF){NQ@J#B-p#51;5?u2`@GNdeZSB1zQ6bPdFiAeUxc)}Gz0=c5d6GC zz-%ELl48K`9g}K;Kw#aZ!0p}%3CR>n9ElVf6cj=v1`~-SfBzr?A<);C;Nt_}=jrL= z=H~9|>fz$z?(FR1=;(~cJ2^N2;O*@J>}_rBt*opqEv+pqtSl@naX0`Ab90=jskw=X zsj;!Kk&y`&Yh-8$fHg3{>gyZo>gwz2>gnj{X>03fYHDFHni?7a7<F|34K+1&G+Iqn z6|JJ8s;sPxLaCroC?zG7qN0+bq9PKhghV106aW<D<>lq%<Piut1Og!|3jj<;Mn*WK zrDdd~q@|>!Bqb#!Bmg9~2n{YS4j?WjCI*86z@ShlxRCE6D<~+atgPg4I6NK?#Cdsn zbb2vJ*=#n0!3CbhV$taw8tp8TnM<Vt@*MEl*&M(#nM?-b42_mUrRHR3v#C@-oB<4j z0R(IsjY+42B{rST%+AiC(Lf)d$pM~D2Qdr8qFNvmra&)BH+f+#U_=_Q1RzW|_Y%dR zvoHk^)dDX(#!qZ2H@6TK0`X=yVad-{q9#Hf1e>)#WIt2Jk0!#ZO{J(gi2pkPxXAVO z^|iG%fk5!>+qadK)vsT_E-rptSXh{xoSK-J9334W85!&EAMEYz>*?uz{J5vHvzyQF zY;V8c+<f!;^&9o|P1mk9)YUaqS6{2FtSK+QQd)Ycq@<k3yI5RY%H<a2=bt}!?jJTg zm&M|M8{Yh6aDdoKO*;6O{39Vjp<w<$3<`s9k&u*@MaU_rsA*udv~_g#^bL%E#aUWe z+uGxuoZY>=1BoHOMUeMJM#sb*{5>i8=&=(gGqb2UEcV&ld~PwXq_n)e;!0(0L-VcM zciQjqyPoz9489m186AH)J@e-6yLaywKYm(XSrx2pL@7N-gJ(KQ@N(aNY@{iFep|>s z^aC6#6X!;o3ebJTtwE4<&6EPItpijwhU04Nh9>&8`?z7`w*l4>PiD-J{AO$JoS)LP zxBE1N>hLDHh@$6FR8uSep_LbLrz4Fw>#~gJTvjlW)-%j$jLoLD^xhh<EAjnQmKTzN zcKtG%D_druM7CK?3_{J!H}fDx;a3G!X{YAJ<Rz!jc@<__F*ww;xX$gU`ToL_bC+7v zu|r&z?A-RtP@H|=enUoWEt?l}WcWKr_HAK!V~qp+ehMZd1`}UmaC5}$WXYk{Pr>^I z1-S<Zb-NPAhIdO26pOnKK3{rOq@EJ*(^WyS3!~UURM>5&VaSG<1{S2%P5uPma`u8< zqIjcS3mQJW^WdL{+qUc}Nb@OGgrs=N-JQ?9krtt!h~Jq+i4h!jy8BB#*Y6?*MhZC( zO=xdyA$O5i?fuioZ3S+NiIHs*ln~Q+CgeavbP?Oh594W)3hm6$SVLx(;cW+UBEk+x zT$no@Pp8C%?s!9VTqr!|@K8^}IJ9?y1v&B=xgOoxrJd^VP~iEh<MV~Ns(@te%&p4; z)1}Ty1w6V(+tIn1Yp@(+{QVF8UB|H#u`{oi+KS6p4q?fkgEhkw7gK9&=E&<W_11Sk z8<(H#?VMiRG0-vlTD7U<N%2~X^nFHQzz3hL6D_Z9uRZlNO|HLQhLOT5<_FitJt9IR z_D#cY7S`IJR|dQDkM2K_`(+#U;S9WzjNTTR0eys3lj<;;h98bTq?Thtu+ob}zbAAi zXHnDtS|4&pnP%M>zSntBHY<JCP$bD58aWo;A82HP?=E%o@2{IEuQEt|;kXf3Y&Hd- z?PCR)3@8#Kup3c->x2jM1CqJ}pVd`A**H#vMQYi`hN|!@P%>4k&rQ|+4D+T@By@?H z$C`K&%<n0Y4Ec}}6>xF&C@v*id6sfjIgH8Mb2f;N^-gp2+Yk&r)~@zia(MP&hk@|1 N61;=FYCZOz`WJ`;-<JRY literal 0 HcmV?d00001 diff --git a/lib/core/widgets/input_field_with_title.dart b/lib/core/widgets/input_field_with_title.dart index 1386c0362..9c194af68 100644 --- a/lib/core/widgets/input_field_with_title.dart +++ b/lib/core/widgets/input_field_with_title.dart @@ -28,7 +28,7 @@ class _InputFieldWithTitleState extends State<InputFieldWithTitle> { alignment: Alignment.center, child: TextField( controller: widget.controller, - style: textTheme.bodySmall, + style: const TextStyle(color: Color(0xFF03162F)), maxLines: widget.maxLines, cursorColor: const Color(0xFFFC6D26), decoration: InputDecoration(hintText: widget.placeHolder, border: const OutlineInputBorder(borderSide: BorderSide.none), contentPadding: const EdgeInsets.only(left: 8)))) diff --git a/lib/core/widgets/markdown_input_box.dart b/lib/core/widgets/markdown_input_box.dart index 7ba9d7040..5c5162f06 100644 --- a/lib/core/widgets/markdown_input_box.dart +++ b/lib/core/widgets/markdown_input_box.dart @@ -52,6 +52,7 @@ class _MarkdownInputBoxState extends State<MarkdownInputBox> with TickerProvider alignment: Alignment.centerLeft, constraints: const BoxConstraints(maxWidth: 150), height: 40, + transform: Matrix4.translationValues(-16, 0, 0), child: TabBar( isScrollable: false, padding: EdgeInsets.zero, @@ -61,7 +62,7 @@ class _MarkdownInputBoxState extends State<MarkdownInputBox> with TickerProvider labelColor: Colors.black, labelStyle: textTheme.titleLarge, unselectedLabelColor: Colors.black54, - labelPadding: EdgeInsets.zero, + labelPadding: const EdgeInsets.only(bottom: 8, top: 8), splashFactory: NoSplash.splashFactory, tabs: [for (String tab in MarkdownInputBox._tabs) Text(tab)], onTap: (index) { @@ -72,29 +73,15 @@ class _MarkdownInputBoxState extends State<MarkdownInputBox> with TickerProvider )), const Flexible(fit: FlexFit.tight, child: SizedBox()), InkWell( - onTap: () => _onAtButtonPressed(), - child: Container( - decoration: const BoxDecoration(color: Colors.white), - alignment: Alignment.centerRight, - height: 40, - width: 50, - child: const Icon( - Icons.alternate_email, - color: Colors.black26, - ), - ), - ), + onTap: () => _onAtButtonPressed(), + child: Container(alignment: Alignment.centerRight, height: 40, width: 50, child: const Icon(Icons.alternate_email, color: Color(0xFF87878C), size: 19))), InkWell( onTap: () => _onImageButtonPressed(), child: Container( - decoration: const BoxDecoration(color: Colors.white), alignment: Alignment.centerRight, height: 40, - width: 50, - child: const Icon( - Icons.photo_outlined, - color: Colors.black26, - ), + width: 30, + child: Image.asset("assets/images/photo_icon.png", height: 16, width: 16), ), ), ], diff --git a/lib/domain/description_content.dart b/lib/domain/description_content.dart new file mode 100644 index 000000000..3d1e990b8 --- /dev/null +++ b/lib/domain/description_content.dart @@ -0,0 +1,16 @@ +import 'package:jihu_gitlab_app/core/settings/settings_provider.dart'; + +class DescriptionContent { + String content; + String pathWithNamespace; + + DescriptionContent._(this.content, this.pathWithNamespace); + + factory DescriptionContent.init(String content, String pathWithNamespace) { + return DescriptionContent._(content, pathWithNamespace); + } + + String get value { + return content.replaceAll("](/uploads/", "](${SettingsProvider().baseUrl}/$pathWithNamespace/uploads/").replaceAll('<br>', '\n').replaceAll('<br/>', '\n'); + } +} diff --git a/lib/domain/issue_detail.dart b/lib/domain/issue_detail.dart index d77c88488..91120655f 100644 --- a/lib/domain/issue_detail.dart +++ b/lib/domain/issue_detail.dart @@ -1,5 +1,5 @@ -import 'package:jihu_gitlab_app/core/settings/settings_provider.dart'; import 'package:jihu_gitlab_app/core/time.dart'; +import 'package:jihu_gitlab_app/domain/description_content.dart'; import 'assignee.dart'; @@ -24,11 +24,7 @@ class IssueDetail { } factory IssueDetail.fromJson(Map<String, dynamic> issueJson, Map<String, dynamic> projectJson) { - var description = (issueJson['description'] ?? '') - .toString() - .replaceAll("[image](/uploads/", "[image](${SettingsProvider().baseUrl}/${projectJson['path_with_namespace']}/uploads/") - .replaceAll('<br>', '\n') - .replaceAll('<br/>', '\n'); + String description = DescriptionContent.init(issueJson['description'] ?? '', projectJson['path_with_namespace']).value; return IssueDetail._(issueJson['id'] ?? 0, issueJson['iid'] ?? 0, issueJson['project_id'] ?? 0, issueJson['title'] ?? '', description, issueJson['created_at'] ?? '', projectJson['name'] ?? '', Assignee.fromJson(issueJson['author'])); } diff --git a/lib/domain/note.dart b/lib/domain/note.dart index 9e10cd7f1..12cddacc0 100644 --- a/lib/domain/note.dart +++ b/lib/domain/note.dart @@ -1,5 +1,5 @@ -import 'package:jihu_gitlab_app/core/settings/settings_provider.dart'; import 'package:jihu_gitlab_app/core/time.dart'; +import 'package:jihu_gitlab_app/domain/description_content.dart'; import 'assignee.dart'; @@ -14,7 +14,7 @@ class Note { Note._(this.id, this.createdAt, this.body, this.system, this.author, this.type); factory Note.fromJson(Map<String, dynamic> json, String pathWithNamespace) { - var replaceAll = json['body'].toString().replaceAll("[image](/uploads/", "[image](${SettingsProvider().baseUrl}/$pathWithNamespace/uploads/"); - return Note._(json['id'], Time.init(json['created_at']), replaceAll, json['system'], Assignee.fromJson(json['author']), json['type'] ?? ""); + var description = DescriptionContent.init(json['body'], pathWithNamespace).value; + return Note._(json['id'], Time.init(json['created_at']), description, json['system'], Assignee.fromJson(json['author']), json['type'] ?? ""); } } diff --git a/lib/modules/issues/issue_creation_page.dart b/lib/modules/issues/issue_creation_page.dart index 195d79dfa..27ca8e0c5 100644 --- a/lib/modules/issues/issue_creation_page.dart +++ b/lib/modules/issues/issue_creation_page.dart @@ -2,7 +2,6 @@ import 'dart:async'; import 'dart:core'; import 'package:flutter/material.dart'; -import 'package:jihu_gitlab_app/core/load_state.dart'; import 'package:jihu_gitlab_app/core/loader.dart'; import 'package:jihu_gitlab_app/core/token_provider.dart'; import 'package:jihu_gitlab_app/core/widgets/avatar_and_name.dart'; @@ -90,35 +89,40 @@ class _IssueCreationPageState extends State<IssueCreationPage> { Navigator.pop(context, true); } }), + actions: [ + Container( + transform: Matrix4.translationValues(-12, 2, 0), + child: TextButton( + onPressed: () { + var title = _issueTitleController.text; + var description = _issueDescriptionController.text; + var labels = _model.selectedLabels.map((e) => e.name).toList().join(","); + Loader.showProgress(context); + _model.create(widget.projectId, title, description: description, labels: labels).then((value) { + Loader.hideProgress(context); + if (value) { + Toast.success(context, 'Created successfully'); + if (widget.from == 'group') { + Navigator.pop(context); + Navigator.pop(context, true); + } else { + Navigator.pop(context, true); + } + } else { + Toast.error(context, 'Failed to create'); + } + }); + }, + child: Text('Create', style: TextStyle(color: Theme.of(context).primaryColor))), + ), + ], ), body: SafeArea(child: Consumer( builder: (context, tokenProvider, child) { if (!TokenProvider.authorized) { return const UnauthorizedView(); } - return IssueCreationView( - projectId: widget.projectId, - model: _model, - issueTitleController: _issueTitleController, - issueDescriptionController: _issueDescriptionController, - onCreateIssueTapped: ({required String title, String? description, String? labels}) async { - Loader.showProgress(context); - _model.create(widget.projectId, title, description: description, labels: labels).then((value) { - Loader.hideProgress(context); - if (value) { - Toast.success(context, 'Created successfully'); - if (widget.from == 'group') { - Navigator.pop(context); - Navigator.pop(context, true); - } else { - Navigator.pop(context, true); - } - } else { - Toast.error(context, 'Failed to create'); - } - }); - }, - ); + return IssueCreationView(projectId: widget.projectId, model: _model, issueTitleController: _issueTitleController, issueDescriptionController: _issueDescriptionController); }, )))); } diff --git a/lib/modules/issues/issue_creation_view.dart b/lib/modules/issues/issue_creation_view.dart index ee6b2b9f9..f35fa96e5 100644 --- a/lib/modules/issues/issue_creation_view.dart +++ b/lib/modules/issues/issue_creation_view.dart @@ -3,11 +3,10 @@ part of 'issue_creation_page.dart'; typedef CreateIssueCallback = void Function({required String title, String? description, String? labels}); class IssueCreationView extends StatefulWidget { - const IssueCreationView({super.key, required this.projectId, required this.model, required this.onCreateIssueTapped, required this.issueTitleController, required this.issueDescriptionController}); + const IssueCreationView({super.key, required this.projectId, required this.model, required this.issueTitleController, required this.issueDescriptionController}); final int projectId; final IssueCreationModel model; - final CreateIssueCallback onCreateIssueTapped; final TextEditingController issueTitleController; final TextEditingController issueDescriptionController; @@ -20,7 +19,6 @@ class _IssueCreationViewState extends State<IssueCreationView> { @override Widget build(BuildContext context) { - final colorScheme = Theme.of(context).colorScheme; return Stack(children: [ Container( padding: EdgeInsets.only(bottom: _bottomActionBoxHeight), @@ -28,60 +26,24 @@ class _IssueCreationViewState extends State<IssueCreationView> { physics: const ScrollPhysics(), child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ InputFieldWithTitle(title: 'Title (required)', placeHolder: 'Write a issue title', controller: widget.issueTitleController), - _buildTitle("Description"), + _buildTitle("Template"), _buildDescriptionTemplatesSelector(), + _buildDescriptionTitle("Description"), MarkdownInputBox(projectId: widget.projectId, controller: widget.issueDescriptionController), - // _buildTitle("Assignees"), - // _buildAssigneeSelector(), _buildAssigneeSelector(), _buildTitle("Labels"), _buildSelectLabelView(), ]))), - Align( - alignment: Alignment.bottomCenter, - child: SizedBox( - width: double.infinity, - height: _bottomActionBoxHeight, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - const Spacer(flex: 1), - Expanded( - flex: 10, - child: InkWell( - onTap: () { - Navigator.pop(context); - }, - child: Container( - decoration: const BoxDecoration(color: Colors.white, borderRadius: BorderRadius.all(Radius.circular(4))), - alignment: Alignment.center, - child: Text('Cancel', style: TextStyle(color: colorScheme.secondary, fontSize: 14, fontWeight: FontWeight.w600)), - ), - )), - const Spacer(flex: 2), - Expanded( - flex: 14, - child: widget.model.createIssueState == LoadState.loadingState - ? const Center(child: CircularProgressIndicator()) - : InkWell( - onTap: () { - var title = widget.issueTitleController.text; - var description = widget.issueDescriptionController.text; - var labels = widget.model.selectedLabels.map((e) => e.name).toList().join(","); - widget.onCreateIssueTapped(title: title, description: description, labels: labels); - }, - child: Container( - alignment: Alignment.center, - decoration: const BoxDecoration(color: Color(0xFFFC6D26), borderRadius: BorderRadius.all(Radius.circular(4))), - child: const Text('Create issue', style: TextStyle(color: Colors.white, fontSize: 14, fontWeight: FontWeight.w600)), - ), - )), - const Spacer(flex: 1) - ], - ))) ]); } + Padding _buildDescriptionTitle(String title) { + return Padding( + padding: const EdgeInsets.fromLTRB(16, 16, 16, 0), + child: Text(title, style: const TextStyle(color: Color(0XFF03162F), fontSize: 16, fontWeight: FontWeight.w600)), + ); + } + Padding _buildTitle(String title) { return Padding( padding: const EdgeInsets.all(16.0), @@ -101,7 +63,7 @@ class _IssueCreationViewState extends State<IssueCreationView> { }); } }, - icon: const Icon(Icons.add)); + icon: const Icon(Icons.add, size: 22, color: Color(0xFF87878C))); final List<Widget> children = []; if (widget.model.selectedLabels.isEmpty) { children.add(const Text("Select label(s)", style: TextStyle(color: Color(0XFF66696D), fontSize: 14, fontWeight: FontWeight.w400))); @@ -110,7 +72,7 @@ class _IssueCreationViewState extends State<IssueCreationView> { children.add(_buildLabelView(e)); } } - children.add(iconButton); + children.add(Container(transform: Matrix4.translationValues(12, 0, 0), child: iconButton)); return Container( width: double.infinity, decoration: const BoxDecoration(border: Border.fromBorderSide(BorderSide(color: Color(0XFFEAEAEA), width: 1)), borderRadius: BorderRadius.all(Radius.circular(4)), color: Colors.white), @@ -179,10 +141,10 @@ class _IssueCreationViewState extends State<IssueCreationView> { widget.issueDescriptionController.text = content; setState(() {}); }, - icon: const Icon(Icons.add)); + icon: const Icon(Icons.add, size: 22, color: Color(0xFF87878C))); final List<Widget> children = []; children.add(Text(widget.model.templateName ?? 'Choose a template', style: const TextStyle(color: Color(0XFF66696D), fontSize: 14, fontWeight: FontWeight.w400))); - children.add(iconButton); + children.add(Container(transform: Matrix4.translationValues(12, 0, 0), child: iconButton)); return Container( width: double.infinity, decoration: const BoxDecoration(border: Border.fromBorderSide(BorderSide(color: Color(0XFFEAEAEA), width: 1)), borderRadius: BorderRadius.all(Radius.circular(4)), color: Colors.white), diff --git a/lib/modules/issues/selectable.dart b/lib/modules/issues/selectable.dart index 7356563ca..3bc650944 100644 --- a/lib/modules/issues/selectable.dart +++ b/lib/modules/issues/selectable.dart @@ -70,7 +70,7 @@ class _SelectableState<T> extends State<Selectable<T>> { _onSelectedCallback(); } }, - icon: const Icon(Icons.add)); + icon: const Icon(Icons.add, size: 22, color: Color(0xFF87878C))); final List<Widget> children = []; if (hasNoData) { children.add(const Text("Select assignee(s)", style: TextStyle(color: Color(0XFF66696D), fontSize: 14, fontWeight: FontWeight.w400))); @@ -79,7 +79,7 @@ class _SelectableState<T> extends State<Selectable<T>> { children.add(_buildSelectedItem(e)); } } - children.add(iconButton); + children.add(Container(transform: Matrix4.translationValues(12, 0, 0), child: iconButton)); return Container( width: double.infinity, decoration: const BoxDecoration(border: Border.fromBorderSide(BorderSide(color: Color(0XFFEAEAEA), width: 1)), borderRadius: BorderRadius.all(Radius.circular(4)), color: Colors.white), diff --git a/test/domain/description_content_test.dart b/test/domain/description_content_test.dart new file mode 100644 index 000000000..f1b6e9d80 --- /dev/null +++ b/test/domain/description_content_test.dart @@ -0,0 +1,28 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:jihu_gitlab_app/domain/description_content.dart'; + +void main() { + test("Include uploads no image", () { + String content = ""; + var descriptionContent = DescriptionContent.init(content, "123"); + expect(descriptionContent.value, ""); + }); + + test("Include uploads has image", () { + String content = ""; + var descriptionContent = DescriptionContent.init(content, "123"); + expect(descriptionContent.value, ""); + }); + + test("Include uploads content", () { + String content = "/uploads"; + var descriptionContent = DescriptionContent.init(content, "123"); + expect(descriptionContent.value, "/uploads"); + }); + + test("Include uploads with https", () { + String content = ""; + var descriptionContent = DescriptionContent.init(content, "123"); + expect(descriptionContent.value, ""); + }); +} diff --git a/test/integration_tests/create_issue_in_sub_group_test.dart b/test/integration_tests/create_issue_in_sub_group_test.dart index 213970762..7a8684cc9 100644 --- a/test/integration_tests/create_issue_in_sub_group_test.dart +++ b/test/integration_tests/create_issue_in_sub_group_test.dart @@ -72,9 +72,8 @@ void main() { await tester.tap(find.text('旗舰版演示 / Demo / Go Demo')); await tester.pumpAndSettle(); expect(find.byType(IssueCreationPage), findsOneWidget); - expect(find.text('Create issue'), findsNWidgets(2)); + expect(find.text('Create'), findsOneWidget); expect(find.text('Title (required)'), findsOneWidget); - expect(find.text('Cancel'), findsOneWidget); // ç”¨æˆ·å¡«å…¥äº†ä¸€äº›ä¿¡æ¯ await tester.enterText( @@ -89,7 +88,7 @@ void main() { 'Demo description'); // 用户点击了创建issue按钮 - await tester.tap(find.widgetWithText(Container, 'Create issue')); + await tester.tap(find.text('Create')); await tester.pumpAndSettle(const Duration(seconds: 1)); // 创建æˆåŠŸï¼Œè¿”å›žäº†ä¸Šä¸€ä¸ªé¡µé¢ @@ -131,9 +130,8 @@ void main() { await tester.tap(find.text('旗舰版演示 / Demo / Go Demo')); await tester.pumpAndSettle(); expect(find.byType(IssueCreationPage), findsOneWidget); - expect(find.text('Create issue'), findsNWidgets(2)); + expect(find.text('Create'), findsOneWidget); expect(find.text('Title (required)'), findsOneWidget); - expect(find.text('Cancel'), findsOneWidget); // ç”¨æˆ·å¡«å…¥äº†ä¸€äº›ä¿¡æ¯ await tester.enterText( @@ -183,9 +181,8 @@ void main() { await tester.tap(find.text('旗舰版演示 / Demo / Go Demo')); await tester.pumpAndSettle(); expect(find.byType(IssueCreationPage), findsOneWidget); - expect(find.text('Create issue'), findsNWidgets(2)); + expect(find.text('Create'), findsOneWidget); expect(find.text('Title (required)'), findsOneWidget); - expect(find.text('Cancel'), findsOneWidget); // ç”¨æˆ·æ·»åŠ descriptionçš„template await tester.tap(find.byKey(const Key("goto-description-selector"))); diff --git a/test/modules/issues/issue_creation_page_test.dart b/test/modules/issues/issue_creation_page_test.dart index 844f2c939..22303c085 100644 --- a/test/modules/issues/issue_creation_page_test.dart +++ b/test/modules/issues/issue_creation_page_test.dart @@ -57,10 +57,9 @@ void main() { ), )); await tester.pumpAndSettle(); - expect(find.text('Create issue'), findsNWidgets(2)); + expect(find.text('Create'), findsOneWidget); expect(find.text('Title (required)'), findsOneWidget); expect(find.text('Write a issue title'), findsOneWidget); - expect(find.text('Cancel'), findsOneWidget); expect(find.byType(MarkdownInputBox), findsOneWidget); UserProvider().fullReset(); @@ -70,6 +69,8 @@ void main() { testWidgets('Should create issue with title and description success', (WidgetTester tester) async { await TokenProvider().reset(Tester.token()); UserProvider().reset(Tester.user()); + when(client.get<Map<String, dynamic>>("/api/v4/user")).thenAnswer((_) => Future(() => Response.of<Map<String, dynamic>>({'id': 5882}))); + HttpClient.setInstance(client); await tester.pumpWidget(const MaterialApp( home: Scaffold( body: IssueCreationPage(projectId: 10000, from: 'group', groupId: 0), @@ -90,8 +91,11 @@ void main() { (widget) => widget is TextField && widget.decoration?.hintText == 'Write a comment here...', ), issueDescription); - await tester.tap(find.text('Create issue').at(1)); - await tester.pumpAndSettle(); + + await tester.tap(find.text('Create')); + for (int i = 0; i < 5; i++) { + await tester.pumpAndSettle(const Duration(seconds: 1)); + } UserProvider().fullReset(); TokenProvider().fullReset(); -- GitLab