diff --git a/cockatrice/src/userinfobox.cpp b/cockatrice/src/userinfobox.cpp index 61e9965e0..0a7d451b0 100644 --- a/cockatrice/src/userinfobox.cpp +++ b/cockatrice/src/userinfobox.cpp @@ -11,20 +11,15 @@ #include #include -#include #include #include -const qint64 SIXTY = 60; -const qint64 HOURS_IN_A_DAY = 24; -const qint64 DAYS_IN_A_YEAR = 365; - UserInfoBox::UserInfoBox(AbstractClient *_client, bool _editable, QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags), client(_client), editable(_editable) { QFont nameFont = nameLabel.font(); nameFont.setBold(true); - nameFont.setPointSize(nameFont.pointSize() * 1.5); + nameFont.setPointSizeF(nameFont.pointSizeF() * 1.5); nameLabel.setFont(nameFont); avatarLabel.setMinimumSize(200, 200); @@ -90,7 +85,6 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user) avatarPixmap = UserLevelPixmapGenerator::generatePixmap(64, userLevel, false, QString::fromStdString(user.privlevel())); } - avatarLabel.setPixmap(avatarPixmap.scaled(400, 200, Qt::KeepAspectRatio, Qt::SmoothTransformation)); nameLabel.setText(QString::fromStdString(user.name())); realNameLabel2.setText(QString::fromStdString(user.real_name())); @@ -129,32 +123,37 @@ void UserInfoBox::updateInfo(const ServerInfo_User &user) QString accountAgeString = tr("Unregistered user"); if (userLevel.testFlag(ServerInfo_User::IsAdmin) || userLevel.testFlag(ServerInfo_User::IsModerator) || userLevel.testFlag(ServerInfo_User::IsRegistered)) { - if (user.accountage_secs() == 0) - accountAgeString = tr("Unknown"); - else { - qint64 seconds = user.accountage_secs(); - qint64 minutes = seconds / SIXTY; - qint64 hours = minutes / SIXTY; - qint64 days = hours / HOURS_IN_A_DAY; - qint64 years = days / DAYS_IN_A_YEAR; - qint64 daysMinusYears = days - (years * DAYS_IN_A_YEAR); - - accountAgeString = ""; - if (years >= 1) { - accountAgeString = QString::number(years); - accountAgeString.append(" "); - accountAgeString.append(years == 1 ? tr("Year") : tr("Years")); - accountAgeString.append(" "); - } - - accountAgeString.append(QString::number(daysMinusYears)); - accountAgeString.append(" "); - accountAgeString.append(days == 1 ? tr("Day") : tr("Days")); - } + accountAgeString = getAgeString(user.accountage_secs()); } accountAgeLabel2.setText(accountAgeString); } +QString UserInfoBox::getAgeString(int ageSeconds) +{ + QString accountAgeString = tr("Unknown"); + if (ageSeconds == 0) + return accountAgeString; + + auto date = QDateTime::fromTime_t(QDateTime::currentSecsSinceEpoch() - ageSeconds).date(); + if (!date.isValid()) + return accountAgeString; + + QString dateString = QLocale().toString(date, QLocale::ShortFormat); + auto now = QDate::currentDate(); + auto daysAndYears = getDaysAndYearsBetween(date, now); + + QString yearString; + if (daysAndYears.second > 0) { + yearString = tr("%n Year(s), ", "amount of years (only shown if more than 0)", daysAndYears.second); + } + accountAgeString = + tr("%10%n Day(s) %20", "amount of years (if more than 0), amount of days, date in local short format", + daysAndYears.first) + .arg(yearString) + .arg(dateString); + return accountAgeString; +} + void UserInfoBox::updateInfo(const QString &userName) { Command_GetUserInfo cmd; @@ -171,6 +170,7 @@ void UserInfoBox::processResponse(const Response &r) { const Response_GetUserInfo &response = r.GetExtension(Response_GetUserInfo::ext); updateInfo(response.user_info()); + resize(sizeHint()); show(); } @@ -257,7 +257,7 @@ void UserInfoBox::processEditResponse(const Response &r) case Response::RespInternalError: default: QMessageBox::critical(this, tr("Error"), - tr("An error occured while trying to update your user informations.")); + tr("An error occurred while trying to update your user information.")); break; } } diff --git a/cockatrice/src/userinfobox.h b/cockatrice/src/userinfobox.h index 27ba1c81e..3f662c64a 100644 --- a/cockatrice/src/userinfobox.h +++ b/cockatrice/src/userinfobox.h @@ -1,6 +1,7 @@ #ifndef USERINFOBOX_H #define USERINFOBOX_H +#include #include #include #include @@ -20,9 +21,18 @@ private: QPushButton editButton, passwordButton, avatarButton; QPixmap avatarPixmap; + static QString getAgeString(int ageSeconds); + public: UserInfoBox(AbstractClient *_client, bool editable, QWidget *parent = nullptr, Qt::WindowFlags flags = {}); void retranslateUi(); + + inline static QPair getDaysAndYearsBetween(const QDate &then, const QDate &now) + { + int years = now.addDays(1 - then.dayOfYear()).year() - then.year(); // there is no yearsTo + int days = then.addYears(years).daysTo(now); + return {days, years}; + } private slots: void processResponse(const Response &r); void processEditResponse(const Response &r); diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 9a8ba8d06..9ca0bfeba 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -1,12 +1,15 @@ enable_testing() add_test(NAME dummy_test COMMAND dummy_test) add_test(NAME expression_test COMMAND expression_test) + +add_test(NAME test_age_formatting COMMAND test_age_formatting) add_test(NAME password_hash_test COMMAND password_hash_test) # Find GTest add_executable(dummy_test dummy_test.cpp) add_executable(expression_test expression_test.cpp) +add_executable(test_age_formatting test_age_formatting.cpp) add_executable(password_hash_test password_hash_test.cpp) find_package(GTest) @@ -37,6 +40,7 @@ if(NOT GTEST_FOUND) SET(GTEST_BOTH_LIBRARIES gtest) add_dependencies(dummy_test gtest) add_dependencies(expression_test gtest) + add_dependencies(test_age_formatting gtest) add_dependencies(password_hash_test gtest) endif() @@ -47,6 +51,7 @@ set(TEST_QT_MODULES Qt5::Widgets) include_directories(${GTEST_INCLUDE_DIRS}) target_link_libraries(dummy_test Threads::Threads ${GTEST_BOTH_LIBRARIES}) target_link_libraries(expression_test cockatrice_common Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) +target_link_libraries(test_age_formatting Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) target_link_libraries(password_hash_test cockatrice_common Threads::Threads ${GTEST_BOTH_LIBRARIES} ${TEST_QT_MODULES}) add_subdirectory(carddatabase) diff --git a/tests/test_age_formatting.cpp b/tests/test_age_formatting.cpp new file mode 100644 index 000000000..88968f252 --- /dev/null +++ b/tests/test_age_formatting.cpp @@ -0,0 +1,44 @@ +#include "../cockatrice/src/userinfobox.h" + +#include "gtest/gtest.h" + +namespace +{ +using dayyear = QPair; + +TEST(AgeFormatting, Zero) +{ + auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2000, 1, 1)); + ASSERT_EQ(got, dayyear(0, 0)) << "these are the same day"; +} + +TEST(AgeFormatting, LeapDay) +{ + auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2000, 3, 1)); + ASSERT_EQ(got, dayyear(2, 0)) << "there is a leap day in between these days"; +} + +TEST(AgeFormatting, LeapYear) +{ + auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 1, 1), QDate(2001, 1, 1)); + ASSERT_EQ(got, dayyear(0, 1)) << "there is a leap day in between these dates, but that's fine"; +} + +TEST(AgeFormatting, LeapDayWithYear) +{ + auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2000, 2, 28), QDate(2001, 3, 1)); + ASSERT_EQ(got, dayyear(1, 1)) << "there is a leap day in between these days but not in the last year"; +} + +TEST(AgeFormatting, LeapDayThisYear) +{ + auto got = UserInfoBox::getDaysAndYearsBetween(QDate(2003, 2, 28), QDate(2004, 3, 1)); + ASSERT_EQ(got, dayyear(2, 1)) << "there is a leap day in between these days this year"; +} +} // namespace + +int main(int argc, char **argv) +{ + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +}