Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #3817 Correct rounding and carry of minutes in client/plugins/utils.js::$elapsedPrettyExtended #3832

Merged
merged 1 commit into from
Jan 15, 2025

Conversation

daneroo
Copy link
Contributor

@daneroo daneroo commented Jan 13, 2025

Correct rounding and carry of minutes in client/plugins/utils.js:: Vue.prototype.$elapsedPrettyExtended

-Add cypress tests for Vue.prototype.$elapsedPrettyExtended function

Note: This is my first PR to the project, any feedback would be appreciated.

Brief summary

In the Audiobookshelf Year In Review, there was a time at which the App reported
"Listening Time" as "44d23h60m", but it should have been "Listening Time" as "45d"

Correct Display Bug Display
Year In Review OK Year In Review BUG

Which issue is fixed?

Fixes #3817

In-depth Description

In client/plugins/utils.js:: Vue.prototype.$elapsedPrettyExtended,
specifically when showSeconds=false, the code to round minutes up (when seconds>=30) did not account for the carry of minutes into hours.

The solution was to add a condition that if the rounded up minutes were now>=60, we should carry minutes into hours.

if (minutes && seconds && !showSeconds) {
  if (seconds >= 30) minutes++
  // new condition
  if (minutes >= 60) {
    hours++ // Increment hours if minutes roll over
    minutes -= 60 // adjust minutes
  }
}

Furthermore, this rounding condition was moved up in the function, before the conditional days handling, to prevent this carry condition from needing to be propagated to days as well.

How have you tested this?

I have added cypress tests (although these are pure functional/non-UI tests) to validate the current behavior of the $elapsedPrettyExtended function.

  • The specific test cases that fix this issue are identified.
  • All tests, except these, were also passed by the original function

Given that the current (existing) cypress tests are not all passing, and do not seem to be run in any GitHub Action CI tasks,
this is how you can run only the newly contributed tests:

cd client; npm ci; npm run generate
// normally just:
// npm test
// but to run only our new tests:
npm run compile-tailwind && npx cypress run --component --browser chrome --spec "cypress/tests/utils/ElapsedPrettyExtended.cy.js"

Test Results

  $elapsedPrettyExtended
    function is on the Vue Prototype
      ✓ exists as a function on Vue.prototype (9ms)
    param default values
      ✓ uses useDays=true showSeconds=true by default (8ms)
      ✓ only useDays=false overrides useDays but keeps showSeconds=true (4ms)
      ✓ explicit useDays=false showSeconds=false overrides both (3ms)
    useDays=false showSeconds=true
      ✓ 0s -> "" (3ms)
      ✓ 1h 1s -> 1h 1s (7ms)
      ✓ 25h 1s -> 25h 1s (4ms)
    useDays=true showSeconds=true
      ✓ 0s -> "" (4ms)
      ✓ 1h 1s -> 1h 1s (3ms)
      ✓ 25h 1s -> 1d 1h 1s (7ms)
    useDays=true showSeconds=false
      ✓ 0s -> "" (3ms)
      ✓ 1h -> 1h (3ms)
      ✓ 1h 1s -> 1h (3ms)
      ✓ 1h 1m -> 1h 1m (3ms)
      ✓ 25h -> 1d 1h (4ms)
      ✓ 25h 1s -> 1d 1h (3ms)
      ✓ 2d -> 2d (5ms)
    rounding useDays=true showSeconds=true
      ✓ 1s -> 1s (3ms)
      ✓ 29.9s -> 30s (3ms)
      ✓ 30s -> 30s (3ms)
      ✓ 30.1s -> 30s (6ms)
      ✓ 59.4s -> 59s (3ms)
      ✓ 59.5s -> 1m (3ms)
      ✓ 59m 29s -> 59m 29s (6ms)
      ✓ 59m 30s -> 59m 30s (2ms)
      ✓ 59m 59.5s -> 1h (3ms)
      ✓ 23h 59m 29s -> 23h 59m 29s (7ms)
      ✓ 23h 59m 30s -> 23h 59m 30s (3ms)
      ✓ 23h 59m 59.5s -> 1d (3ms)
      ✓ 44d 23h 59m 30s -> 44d 23h 59m 30s (5ms)
    rounding useDays=true showSeconds=false
      ✓ 1s -> "" (7ms)
      ✓ 29.9s -> "" (3ms)
      ✓ 30s -> "" (2ms)
      ✓ 30.1s -> "" (6ms)
      ✓ 59.4s -> "" (3ms)
      ✓ 59.5s -> 1m (3ms)
      ✓ 1m 29.5s -> 2m (3ms)
      ✓ 59m 29s -> 59m (3ms)
      ✓ 59m 30s -> 1h (3ms)
      ✓ 59m 59.5s -> 1h (6ms)
      ✓ 23h 59m 29s -> 23h 59m (3ms)
      ✓ 23h 59m 30s -> 1d (3ms)
      ✓ 23h 59m 59.5s -> 1d (6ms)
      ✓ 44d 23h 59m 30s -> 45d (2ms)
    empty values
      with days and seconds
        ✓ null input (6ms)
        ✓ undefined input (6ms)
        ✓ zero (3ms)
        ✓ rounds to zero (2ms)
      with days, no seconds
        ✓ null input (3ms)
        ✓ undefined input (2ms)
        ✓ zero (2ms)
        ✓ rounds to zero (3ms)
      no days, with seconds
        ✓ null input (4ms)
        ✓ undefined input (6ms)
        ✓ zero (3ms)
        ✓ rounds to zero (3ms)
      no days, no seconds
        ✓ null input (3ms)
        ✓ undefined input (3ms)
        ✓ zero (3ms)
        ✓ rounds to zero (3ms)


  60 passing (440ms)


  (Results)

  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ Tests:        60                                                                               │
  │ Passing:      60                                                                               │
  │ Failing:      0                                                                                │
  │ Pending:      0                                                                                │
  │ Skipped:      0                                                                                │
  │ Screenshots:  0                                                                                │
  │ Video:        false                                                                            │
  │ Duration:     0 seconds                                                                        │
  │ Spec Ran:     ElapsedPrettyExtended.cy.js                                                      │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘


====================================================================================================

  (Run Finished)


       Spec                                              Tests  Passing  Failing  Pending  Skipped  
  ┌────────────────────────────────────────────────────────────────────────────────────────────────┐
  │ ✔  ElapsedPrettyExtended.cy.js              441ms       60       60        -        -        - │
  └────────────────────────────────────────────────────────────────────────────────────────────────┘
    ✔  All specs passed!                        441ms       60       60        -        -        -  

I also ran a brute force test (not submitted) to guarantee that the corrected function did not change the function's behaviour for cases other than those identified in this bug fix. i.e. I compared the value of the original function vs the fixed version for all values of 'seconds' in [0s, 101 days] in increments of 0.5 seconds

Screenshots

None

Correct rounding and carry of minutes in Vue.prototype.$elapsedPrettyExtended

-Add cypress tests for Vue.prototype.$elapsedPrettyExtended function
@advplyr
Copy link
Owner

advplyr commented Jan 15, 2025

This is great, thank you for the thorough testing!

@advplyr advplyr merged commit 9bbb23b into advplyr:master Jan 15, 2025
5 checks passed
@daneroo daneroo deleted the fix_rounding_elapsedPrettyExtended branch January 17, 2025 01:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[Bug]: Rounding Display Error in Listen Time
2 participants