Skip to content

Commit afc563d

Browse files
committed
chore: fix unit test
1 parent c6edd1a commit afc563d

File tree

8 files changed

+97
-68
lines changed

8 files changed

+97
-68
lines changed

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/context_builder.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ part of 'cell_service.dart';
22

33
typedef GridCellContext = _GridCellContext<Cell, String>;
44
typedef GridSelectOptionCellContext = _GridCellContext<SelectOptionCellData, String>;
5-
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCellPersistenceData>;
5+
typedef GridDateCellContext = _GridCellContext<DateCellData, DateCalData>;
66

77
class GridCellContextBuilder {
88
final GridCellCache _cellCache;

frontend/app_flowy/lib/workspace/application/grid/cell/cell_service/data_persistence.dart

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,23 +31,26 @@ class CellDataPersistence implements _GridCellDataPersistence<String> {
3131
}
3232

3333
@freezed
34-
class DateCellPersistenceData with _$DateCellPersistenceData {
35-
const factory DateCellPersistenceData({required DateTime date, String? time}) = _DateCellPersistenceData;
34+
class DateCalData with _$DateCalData {
35+
const factory DateCalData({required DateTime date, String? time}) = _DateCellPersistenceData;
3636
}
3737

38-
class DateCellDataPersistence implements _GridCellDataPersistence<DateCellPersistenceData> {
38+
class DateCellDataPersistence implements _GridCellDataPersistence<DateCalData> {
3939
final GridCell gridCell;
4040
DateCellDataPersistence({
4141
required this.gridCell,
4242
});
4343

4444
@override
45-
Future<Option<FlowyError>> save(DateCellPersistenceData data) {
45+
Future<Option<FlowyError>> save(DateCalData data) {
4646
var payload = DateChangesetPayload.create()..cellIdentifier = _cellIdentifier(gridCell);
4747

4848
final date = (data.date.millisecondsSinceEpoch ~/ 1000).toString();
4949
payload.date = date;
50-
payload.time = data.time ?? "";
50+
51+
if (data.time != null) {
52+
payload.time = data.time!;
53+
}
5154

5255
return GridEventUpdateDateCell(payload).send().then((result) {
5356
return result.fold(

frontend/app_flowy/lib/workspace/application/grid/cell/date_cal_bloc.dart

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import 'dart:async';
99
import 'cell_service/cell_service.dart';
1010
import 'package:dartz/dartz.dart';
1111
import 'package:protobuf/protobuf.dart';
12-
// import 'package:fixnum/fixnum.dart' as $fixnum;
12+
import 'package:fixnum/fixnum.dart' as $fixnum;
1313
part 'date_cal_bloc.freezed.dart';
1414

1515
class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
@@ -34,7 +34,11 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
3434
setFocusedDay: (focusedDay) {
3535
emit(state.copyWith(focusedDay: focusedDay));
3636
},
37-
didReceiveCellUpdate: (value) {},
37+
didReceiveCellUpdate: (DateCellData cellData) {
38+
final dateData = dateDataFromCellData(cellData);
39+
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
40+
emit(state.copyWith(dateData: dateData, time: time));
41+
},
3842
setIncludeTime: (includeTime) async {
3943
await _updateTypeOption(emit, includeTime: includeTime);
4044
},
@@ -53,11 +57,8 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
5357
}
5458

5559
Future<void> _updateDateData(Emitter<DateCalState> emit, {DateTime? date, String? time}) {
56-
final DateCellPersistenceData newDateData = state.dateData.fold(
57-
() {
58-
var newDateData = DateCellPersistenceData(date: date ?? DateTime.now());
59-
return newDateData.copyWith(time: time);
60-
},
60+
final DateCalData newDateData = state.dateData.fold(
61+
() => DateCalData(date: date ?? DateTime.now(), time: time),
6162
(dateData) {
6263
var newDateData = dateData;
6364
if (date != null && !isSameDay(newDateData.date, date)) {
@@ -74,7 +75,7 @@ class DateCalBloc extends Bloc<DateCalEvent, DateCalState> {
7475
return _saveDateData(emit, newDateData);
7576
}
7677

77-
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCellPersistenceData newDateData) async {
78+
Future<void> _saveDateData(Emitter<DateCalState> emit, DateCalData newDateData) async {
7879
if (state.dateData == Some(newDateData)) {
7980
return;
8081
}
@@ -173,31 +174,48 @@ class DateCalState with _$DateCalState {
173174
required DateTypeOption dateTypeOption,
174175
required CalendarFormat format,
175176
required DateTime focusedDay,
176-
required String time,
177177
required Option<String> timeFormatError,
178-
required Option<DateCellPersistenceData> dateData,
178+
required Option<DateCalData> dateData,
179+
required String? time,
179180
}) = _DateCalState;
180181

181182
factory DateCalState.initial(
182183
DateTypeOption dateTypeOption,
183184
DateCellData? cellData,
184185
) {
185-
Option<DateCellPersistenceData> dateData = none();
186-
final time = cellData?.time ?? "";
187-
if (cellData != null) {
188-
// final timestamp = $fixnum.Int64.parseInt(cellData.timestamp).toInt();
189-
final timestamp = cellData.timestamp * 1000;
190-
final selectedDay = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
191-
dateData = Some(DateCellPersistenceData(date: selectedDay, time: time));
192-
}
193-
186+
Option<DateCalData> dateData = dateDataFromCellData(cellData);
187+
final time = dateData.foldRight("", (dateData, previous) => dateData.time);
194188
return DateCalState(
195189
dateTypeOption: dateTypeOption,
196190
format: CalendarFormat.month,
197191
focusedDay: DateTime.now(),
198-
dateData: dateData,
199192
time: time,
193+
dateData: dateData,
200194
timeFormatError: none(),
201195
);
202196
}
203197
}
198+
199+
Option<DateCalData> dateDataFromCellData(DateCellData? cellData) {
200+
String? time = timeFromCellData(cellData);
201+
Option<DateCalData> dateData = none();
202+
if (cellData != null) {
203+
final timestamp = cellData.timestamp * 1000;
204+
final date = DateTime.fromMillisecondsSinceEpoch(timestamp.toInt());
205+
dateData = Some(DateCalData(date: date, time: time));
206+
}
207+
return dateData;
208+
}
209+
210+
$fixnum.Int64 timestampFromDateTime(DateTime dateTime) {
211+
final timestamp = (dateTime.millisecondsSinceEpoch ~/ 1000);
212+
return $fixnum.Int64(timestamp);
213+
}
214+
215+
String? timeFromCellData(DateCellData? cellData) {
216+
String? time;
217+
if (cellData?.hasTime() ?? false) {
218+
time = cellData?.time;
219+
}
220+
return time;
221+
}

frontend/app_flowy/lib/workspace/presentation/plugins/grid/src/widgets/cell/date_cell/calendar.dart

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,11 @@ class _TimeTextFieldState extends State<_TimeTextField> {
254254
@override
255255
Widget build(BuildContext context) {
256256
final theme = context.watch<AppTheme>();
257-
return BlocBuilder<DateCalBloc, DateCalState>(
257+
return BlocConsumer<DateCalBloc, DateCalState>(
258+
listener: (context, state) {
259+
_controller.text = state.time ?? "";
260+
},
261+
listenWhen: (p, c) => p.time != c.time,
258262
builder: (context, state) {
259263
if (state.dateTypeOption.includeTime) {
260264
return Padding(

frontend/rust-lib/flowy-grid/src/event_handler.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,7 @@ pub(crate) async fn get_date_cell_data_handler(
289289
Some(field_meta) => {
290290
let cell_meta = editor.get_cell_meta(&params.row_id, &params.field_id).await?;
291291
let type_option = DateTypeOption::from(&field_meta);
292-
let date_cell_data = type_option.date_cell_data(&cell_meta)?;
292+
let date_cell_data = type_option.make_date_cell_data(&cell_meta)?;
293293
data_result(date_cell_data)
294294
}
295295
}

frontend/rust-lib/flowy-grid/src/services/field/type_options/date_type_option.rs

Lines changed: 23 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,12 @@ use crate::services::row::{CellContentChangeset, CellDataOperation, DecodedCellD
55
use bytes::Bytes;
66
use chrono::format::strftime::StrftimeItems;
77
use chrono::NaiveDateTime;
8-
use diesel::types::Time;
98
use flowy_derive::{ProtoBuf, ProtoBuf_Enum};
109
use flowy_error::{internal_error, ErrorCode, FlowyError, FlowyResult};
1110
use flowy_grid_data_model::entities::{
1211
CellChangeset, CellMeta, FieldMeta, FieldType, TypeOptionDataDeserializer, TypeOptionDataEntry,
1312
};
1413
use serde::{Deserialize, Serialize};
15-
use std::ops::Add;
1614
use std::str::FromStr;
1715
use strum_macros::EnumIter;
1816

@@ -79,7 +77,7 @@ impl DateTypeOption {
7977
}
8078
}
8179

82-
pub fn date_cell_data(&self, cell_meta: &Option<CellMeta>) -> FlowyResult<DateCellData> {
80+
pub fn make_date_cell_data(&self, cell_meta: &Option<CellMeta>) -> FlowyResult<DateCellData> {
8381
if cell_meta.is_none() {
8482
return Ok(DateCellData::default());
8583
}
@@ -112,27 +110,28 @@ impl DateTypeOption {
112110
utc: &chrono::DateTime<chrono::Utc>,
113111
time: &Option<String>,
114112
) -> FlowyResult<i64> {
115-
let mut date_str = format!(
116-
"{}",
117-
utc.format_with_items(StrftimeItems::new(self.date_format.format_str()))
118-
);
119-
120113
if let Some(time_str) = time.as_ref() {
121114
if !time_str.is_empty() {
122-
date_str = date_str.add(&time_str);
123-
}
124-
}
125-
let fmt = self.date_fmt(time);
126-
match NaiveDateTime::parse_from_str(&date_str, &fmt) {
127-
Ok(native) => {
128-
let utc = self.utc_date_time_from_native(native);
129-
Ok(utc.timestamp())
130-
}
131-
Err(_e) => {
132-
let msg = format!("Parse {} with format: {} failed", date_str, fmt);
133-
Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg))
115+
let date_str = format!(
116+
"{}{}",
117+
utc.format_with_items(StrftimeItems::new(self.date_format.format_str())),
118+
&time_str
119+
);
120+
121+
return match NaiveDateTime::parse_from_str(&date_str, &self.date_fmt(time)) {
122+
Ok(native) => {
123+
let utc = self.utc_date_time_from_native(native);
124+
Ok(utc.timestamp())
125+
}
126+
Err(_e) => {
127+
let msg = format!("Parse {} failed", date_str);
128+
Err(FlowyError::new(ErrorCode::InvalidDateTimeFormat, &msg))
129+
}
130+
};
134131
}
135132
}
133+
134+
return Ok(utc.timestamp());
136135
}
137136
}
138137

@@ -170,7 +169,7 @@ impl CellDataOperation for DateTypeOption {
170169
let timestamp = self.timestamp_from_utc_with_time(&utc, &time)?;
171170
DateCellDataSerde::new(timestamp, time, &self.time_format)
172171
}
173-
_ => DateCellDataSerde::from_timestamp(date_timestamp, &self.time_format),
172+
_ => DateCellDataSerde::from_timestamp(date_timestamp, Some(default_time_str(&self.time_format))),
174173
},
175174
};
176175

@@ -312,11 +311,8 @@ impl DateCellDataSerde {
312311
}
313312
}
314313

315-
fn from_timestamp(timestamp: i64, time_format: &TimeFormat) -> Self {
316-
Self {
317-
timestamp,
318-
time: Some(default_time_str(time_format)),
319-
}
314+
pub(crate) fn from_timestamp(timestamp: i64, time: Option<String>) -> Self {
315+
Self { timestamp, time }
320316
}
321317

322318
fn to_string(self) -> String {
@@ -614,11 +610,7 @@ mod tests {
614610
}
615611

616612
fn data(s: i64) -> String {
617-
let json = serde_json::to_string(&DateCellDataSerde {
618-
timestamp: s,
619-
time: None,
620-
})
621-
.unwrap();
613+
let json = serde_json::to_string(&DateCellDataSerde::from_timestamp(s, None)).unwrap();
622614
TypeOptionCellData::new(&json, FieldType::DateTime).json()
623615
}
624616
}

frontend/rust-lib/flowy-grid/src/services/field/type_options/text_type_option.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,8 @@ mod tests {
7878

7979
// date
8080
let date_time_field_meta = FieldBuilder::from_field_type(&FieldType::DateTime).build();
81-
let data = TypeOptionCellData::new("1647251762", FieldType::DateTime).json();
81+
let json = serde_json::to_string(&DateCellDataSerde::from_timestamp(1647251762, None)).unwrap();
82+
let data = TypeOptionCellData::new(&json, FieldType::DateTime).json();
8283
assert_eq!(
8384
type_option.decode_cell_data(data, &date_time_field_meta).content,
8485
"Mar 14,2022".to_owned()

frontend/rust-lib/flowy-grid/tests/grid/grid_test.rs

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ use crate::grid::script::EditorScript::*;
22
use crate::grid::script::*;
33
use chrono::NaiveDateTime;
44
use flowy_grid::services::field::{
5-
MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset, SingleSelectTypeOption,
6-
SELECTION_IDS_SEPARATOR,
5+
DateCellContentChangeset, MultiSelectTypeOption, SelectOption, SelectOptionCellContentChangeset,
6+
SingleSelectTypeOption, SELECTION_IDS_SEPARATOR,
77
};
88
use flowy_grid::services::row::{decode_cell_data, CreateRowMetaBuilder};
99
use flowy_grid_data_model::entities::{
@@ -240,7 +240,9 @@ async fn grid_row_add_cells_test() {
240240
builder.add_cell(&field.id, "18,443".to_owned()).unwrap();
241241
}
242242
FieldType::DateTime => {
243-
builder.add_cell(&field.id, "1647251762".to_owned()).unwrap();
243+
builder
244+
.add_cell(&field.id, make_date_cell_string("1647251762"))
245+
.unwrap();
244246
}
245247
FieldType::SingleSelect => {
246248
let type_option = SingleSelectTypeOption::from(field);
@@ -278,10 +280,11 @@ async fn grid_row_add_date_cell_test() {
278280
date_field = Some(field.clone());
279281
NaiveDateTime::from_timestamp(123, 0);
280282
// The data should not be empty
281-
assert!(builder.add_cell(&field.id, "".to_owned()).is_err());
282-
283-
assert!(builder.add_cell(&field.id, "123".to_owned()).is_ok());
284-
assert!(builder.add_cell(&field.id, format!("{}", timestamp)).is_ok());
283+
assert!(builder.add_cell(&field.id, "".to_string()).is_err());
284+
assert!(builder.add_cell(&field.id, make_date_cell_string("123")).is_ok());
285+
assert!(builder
286+
.add_cell(&field.id, make_date_cell_string(&timestamp.to_string()))
287+
.is_ok());
285288
}
286289
}
287290
let context = builder.build();
@@ -315,7 +318,7 @@ async fn grid_cell_update() {
315318
let data = match field_meta.field_type {
316319
FieldType::RichText => "".to_string(),
317320
FieldType::Number => "123".to_string(),
318-
FieldType::DateTime => "123".to_string(),
321+
FieldType::DateTime => make_date_cell_string("123"),
319322
FieldType::SingleSelect => {
320323
let type_option = SingleSelectTypeOption::from(field_meta);
321324
SelectOptionCellContentChangeset::from_insert(&type_option.options.first().unwrap().id).to_str()
@@ -363,3 +366,11 @@ async fn grid_cell_update() {
363366

364367
test.run_scripts(scripts).await;
365368
}
369+
370+
fn make_date_cell_string(s: &str) -> String {
371+
serde_json::to_string(&DateCellContentChangeset {
372+
date: Some(s.to_string()),
373+
time: None,
374+
})
375+
.unwrap()
376+
}

0 commit comments

Comments
 (0)