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

API Refactor - DeleteWorkspace - Offline pattern B #10491

Merged
merged 15 commits into from
Sep 22, 2022

Conversation

aldo-expensify
Copy link
Contributor

@aldo-expensify aldo-expensify commented Aug 23, 2022

Needs these PRs:

Details

Fixed Issues

$ https://github.com/Expensify/Expensify/issues/215184

Tests

  1. Create 3 accounts and verify them, i.e.:
  2. Login with workspace-owner@expensifail.com and create workspace inviting workspace-employee@expensifail.com as an employee and workspace-admin@expensifail.com as an admin. To invite a user as an admin, for now, you will have to change the code here from {email: login} to {email: login, role: 'admin'} right before inviting the admin.
  3. You should have 3 policy expense chats, one for each workspace member, and two rooms: #announce and #admin
    Screen Shot 2022-09-02 at 4 16 29 PM
  4. Send a message in each chat and room so when we archive them, they don't hide
  5. Log in with each account in a different chrome browser session:
    • The admin workspace-admin@expensifail.com should see all policy expense chats and the two rooms (the same chats the owner can see)
    • The employee workspace-employee@expensifail.com should see only his policy expense chat and the #announce room
      Screen Shot 2022-09-02 at 4 20 11 PM
  6. [Optional: only if you managed to add an admin to the workspace] With the workspace admin workspace-admin@expensifail.com:
    • open the workspace's settings, click the 3 vertical dots on the top right corner and click "Delete Workspace"
    • You should see an error of not being able to delete the workspace if you are not the owner
      Screen Shot 2022-09-02 at 5 56 12 PM
  7. With the workspace owner:
    • Open the workspace's settings, click the 3 vertical dots on the top right corner and click "Delete Workspace"
    • For the workspace admins (the added admin and the owner):
      • The 3 policy expense chats and the 2 rooms (#announce and #admins) should change to archived
        Screen Shot 2022-09-02 at 5 59 28 PM
      • The workspace should disappear
        Screen Shot 2022-09-02 at 5 59 46 PM
    • For the workspace employee:
      • The #announce room and the policy expense chat should change to archived
        Screen Shot 2022-09-02 at 6 00 10 PM

Offline test:

  1. Create a workspace again
  2. Go to Settings, open the Workspace Settings
  3. Put yourself offline using chrome dev tools network tab
  4. Click "Delete Workspace"
  5. You should see the workspace entry with a strikethrough
    image
  6. Enable the internet connection again
  7. The workspace should get deleted successfully

Online section

  1. Create verified account 1 in NewDot
  2. Create verified account 2 in NewDot
  3. Log in with both accounts in different browser sessions (you can use incognito)
  4. Create a workspace with account 1 and invite account 2 as a member
    • Check that you have two new chats in account 1:
      • The main workspace chat
      • The workspace chat with account 2
    • Reload the page in the browser that is logged with account 2
    • Check that the account 2 has the second workspace chat
  5. With account 1, delete the workspace:
    • You should be taken back to the settings page (outside of the workspace)
    • without refreshing, check that the chats get archived for both user
    • without refreshing, Check that the workspace get removed from the account 1

Offline section

  1. Create another workspace with account 1 and invite account 2
  2. Open the workspace settings
  3. Make yourself offline (chrome tools, network tab, throttle network)
  4. Click Delete Workspace (in the menu that appears when the 3 vertical dots are clicked)
  5. You should be taken back to the settings page (outside of the workspace)
  6. You should see the workspace with a strikethrough, and you shouldn't be able to click it (disabled)
  • Verify that no errors appear in the JS console

PR Review Checklist

Contributor (PR Author) Checklist

  • I linked the correct issue in the ### Fixed Issues section above
  • I wrote clear testing steps that cover the changes made in this PR
    • I added steps for local testing in the Tests section
    • I added steps for Staging and/or Production testing in the QA steps section
    • I added steps to cover failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I included screenshots or videos for tests on all platforms
  • I ran the tests on all platforms & verified they passed on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I followed proper code patterns (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick)
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I followed the guidelines as stated in the Review Guidelines
  • I tested other components that can be impacted by my changes (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar are working as expected)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR author checklist, including those that don't apply to this PR.

PR Reviewer Checklist

The Contributor+ will copy/paste it into a new comment and complete it after the author checklist is completed

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • I verified there are no console errors (if there's a console error not related to the PR, report it or open an issue for it to be fixed)
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

QA Steps

See "Tests / QA" section above

This is the same as the "Tests" section, but without the admin account because we cannot add that through the UI in staging/production

  1. Create 2 accounts and verify them, i.e.:
  2. Login with workspace-owner@expensifail.com and create workspace inviting workspace-employee@expensifail.com
  3. You should have 2 policy expense chats, one for each workspace member, and two rooms: #announce and #admins
    Screen Shot 2022-09-02 at 4 16 29 PM
  4. Send a message in each chat and room so when we archive them, they don't hide
  5. Log in with each account in a different chrome browser session:
    • The employee workspace-employee@expensifail.com should see only his policy expense chat and the #announce room
      Screen Shot 2022-09-02 at 4 20 11 PM
  6. With the workspace owner:
    • Open the workspace's settings, click the 3 vertical dots on the top right corner and click "Delete Workspace"
    • For the workspace admins (the added admin and the owner):
      • The 2 policy expense chats and the 2 rooms (#announce and #admins) should change to archived
        Screen Shot 2022-09-02 at 5 59 28 PM
      • The workspace should disappear
        Screen Shot 2022-09-02 at 5 59 46 PM
    • For the workspace employee:
      • The #announce room and the policy expense chat should change to archived
        Screen Shot 2022-09-02 at 6 00 10 PM

Offline test:

  1. Create a workspace again
  2. Go to Settings, open the Workspace Settings
  3. Put yourself offline using chrome dev tools network tab
  4. Click "Delete Workspace"
  5. You should see the workspace entry with a strikethrough
    image
  6. Enable the internet connection again
  7. The workspace should get deleted successfully
  • Verify that no errors appear in the JS console

Screenshots

Web

After deleting the workspace while being offline:

image

The backend pushing an error:

image

Mobile Web

Desktop

iOS

Android

@@ -22,7 +23,7 @@ Onyx.connect({
return;
}

allPolicies[key] = {...allPolicies[key], ...val};
allPolicies[key] = val;
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This was not allowing us to remove keys (like errors) from a policy. It kept adding it back.

@aldo-expensify aldo-expensify self-assigned this Sep 2, 2022
if (hasPolicyMemberError(policyMemberList) || hasPolicyError(policy) || hasCustomUnitsError(policy)) {
if (hasPolicyMemberError(policyMemberList) || hasCustomUnitsError(policy)) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is to remove the BrickRoad indicator status from the workspace line if the error is in the workspace itself, otherwise we get a double red dot:

Screen Shot 2022-09-02 at 5 48 17 PM

@aldo-expensify aldo-expensify changed the title API Refactor - DeleteWorkspace - Offline pattern B [HOLD https://github.com/Expensify/Web-Expensify/pull/34659] API Refactor - DeleteWorkspace - Offline pattern B Sep 2, 2022
@Beamanator Beamanator changed the title [HOLD https://github.com/Expensify/Web-Expensify/pull/34659] API Refactor - DeleteWorkspace - Offline pattern B [HOLD Web-E#34659] API Refactor - DeleteWorkspace - Offline pattern B Sep 12, 2022
@luacmartins
Copy link
Contributor

Web-E PR is on prod and hold is removed. @aldo-expensify is ooo until Sep 27th, so I'm bumping @stitesExpensify @mananjadhav for reviews!

@luacmartins luacmartins changed the title [HOLD Web-E#34659] API Refactor - DeleteWorkspace - Offline pattern B API Refactor - DeleteWorkspace - Offline pattern B Sep 14, 2022
@mananjadhav
Copy link
Collaborator

@luacmartins I cannot access the issue URL mentioned in the Fixes Issue, can I get a dump of any information relevant related to the issue.

@mananjadhav
Copy link
Collaborator

No. Believe. me I tried refresh, hard refresh, signout and signin. It doesn't load up. Anyway to check from the backend? My username is mananjadhav+wkowner@gmail.com

@luacmartins
Copy link
Contributor

luacmartins commented Sep 22, 2022

@mananjadhav oooh I think the problem is that that account is not in the policyExpenseChat beta. I just added it to the beta, can you please try again? It may take up to an hour for the beta changes to kick in

@mananjadhav
Copy link
Collaborator

mananjadhav commented Sep 22, 2022

Okay thanks that did it. I can see the chats from the previous workspaces as well. Thanks for helping out @luacmartins.

image

🎀 👀 🎀 
C+ reviewed

  • I have verified the author checklist is complete (all boxes are checked off).
  • I verified the correct issue is linked in the ### Fixed Issues section above
  • I verified testing steps are clear and they cover the changes made in this PR
    • I verified the steps for local testing are in the Tests section
    • I verified the steps for Staging and/or Production testing are in the QA steps section
    • I verified the steps cover any possible failure scenarios (i.e. verify an input displays the correct error message if the entered data is not correct)
    • I turned off my network connection and tested it while offline to ensure it matches the expected behavior (i.e. verify the default avatar icon is displayed if app is offline)
  • I checked that screenshots or videos are included for tests on all platforms
  • I verified tests pass on all platforms & I tested again on:
    • iOS / native
    • Android / native
    • iOS / Safari
    • Android / Chrome
    • MacOS / Chrome
    • MacOS / Desktop
  • If there are any errors in the console that are unrelated to this PR, I either fixed them (preferred) or linked to where I reported them in Slack
  • I verified proper code patterns were followed (see Reviewing the code)
    • I verified that any callback methods that were added or modified are named for what the method does and never what callback they handle (i.e. toggleReport and not onIconClick).
    • I verified that comments were added to code that is not self explanatory
    • I verified that any new or modified comments were clear, correct English, and explained "why" the code was doing something instead of only explaining "what" the code was doing.
    • I verified any copy / text shown in the product was added in all src/languages/* files
    • I verified any copy / text that was added to the app is correct English and approved by marketing by tagging the marketing team on the original GH to get the correct copy.
    • I verified proper file naming conventions were followed for any new files or renamed files. All non-platform specific files are named after what they export and are not named "index.js". All platform-specific files are named for the platform the code supports as outlined in the README.
    • I verified the JSDocs style guidelines (in STYLE.md) were followed
  • If a new code pattern is added I verified it was agreed to be used by multiple Expensify engineers
  • I verified that this PR follows the guidelines as stated in the Review Guidelines
  • I verified other components that can be impacted by these changes have been tested, and I retested again (i.e. if the PR modifies a shared library or component like Avatar, I verified the components using Avatar have been tested & I retested again)
  • I verified all code is DRY (the PR doesn't include any logic written more than once, with the exception of tests)
  • I verified any variables that can be defined as constants (ie. in CONST.js or at the top of the file that uses the constant) are defined as such
  • If a new component is created I verified that:
    • A similar component doesn't exist in the codebase
    • All props are defined accurately and each prop has a /** comment above it */
    • Any functional components have the displayName property
    • The file is named correctly
    • The component has a clear name that is non-ambiguous and the purpose of the component can be inferred from the name alone
    • The only data being stored in the state is data necessary for rendering and nothing else
    • For Class Components, any internal methods passed to components event handlers are bound to this properly so there are no scoping issues (i.e. for onClick={this.submit} the method this.submit should be bound to this in the constructor)
    • Any internal methods bound to this are necessary to be bound (i.e. avoid this.submit = this.submit.bind(this); if this.submit is never passed to a component event handler like onClick)
    • All JSX used for rendering exists in the render method
    • The component has the minimum amount of code necessary for its purpose, and it is broken down into smaller components in order to separate concerns and functions
  • If a new CSS style is added I verified that:
    • A similar style doesn't already exist
    • The style can't be created with an existing StyleUtils function (i.e. StyleUtils.getBackgroundAndBorderStyle(themeColors.componentBG)
  • If the PR modifies a generic component, I tested and verified that those changes do not break usages of that component in the rest of the App (i.e. if a shared library or component like Avatar is modified, I verified that Avatar is working as expected in all cases)
  • If the PR modifies a component related to any of the existing Storybook stories, I tested and verified all stories for that component are still working as expected.
  • I have checked off every checkbox in the PR reviewer checklist, including those that don't apply to this PR.

@luacmartins
Copy link
Contributor

@stitesExpensify can you re-review please?

@luacmartins
Copy link
Contributor

@mananjadhav glad it worked! Would you mind also approving the PR?

Copy link
Collaborator

@mananjadhav mananjadhav left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Filled the checklist in another comment.

@stitesExpensify stitesExpensify merged commit 1b4721e into main Sep 22, 2022
@stitesExpensify stitesExpensify deleted the aldo_delete-workspace-api-refactor branch September 22, 2022 18:35
@melvin-bot melvin-bot bot added the Emergency label Sep 22, 2022
@melvin-bot
Copy link

melvin-bot bot commented Sep 22, 2022

@stitesExpensify looks like this was merged without passing tests. Please add a note explaining why this was done and remove the Emergency label if this is not an emergency.

@OSBotify
Copy link
Contributor

✋ This PR was not deployed to staging yet because QA is ongoing. It will be automatically deployed to staging after the next production release.

@stitesExpensify
Copy link
Contributor

Removing emergency, tests were passing

@OSBotify
Copy link
Contributor

🚀 Deployed to staging by @stitesExpensify in version: 1.2.6-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

@aldo-expensify
Copy link
Contributor Author

Thank you guys for taking this to the end ❤️ !

@roryabraham
Copy link
Contributor

roryabraham commented Sep 26, 2022

I was looking at this issue because it came up on the deploy checklist, and did the following:

  1. Create two accounts, workspace-owner and workspace-employee
  2. Sign in as workspace-owner, create a workspace
  3. Invite workspace-employee
  4. Verify that workspace-owner sees:
    1. The workspace in settings ✅
    2. The #admins room ✅
    3. The #announce room ✅
    4. Their own workspace chat ✅
    5. The workspace chat for workspace-employee
  5. Verify that workspace-employee sees:
    1. The #announce room ✅
    2. Their own workspace chat ❌
  6. As workspace-owner, send a chat in all the reports listed above.
    1. Note: now the workspace chat shows up for the workspace-employee, but it did not show up before, nor was it discoverable via the search or request money pages.
  7. As workspace-owner, turn off wifi / go offline.
  8. Delete the workspace:
    1. Workspace disappears in settings ✅
    2. #admins room is not archived ❌
    3. #announce room is archived ❌
    4. Workspace chats are not archived ❌
  9. Come back online.
  10. Nothing changes, except that the workspace re-appears in settings as "slashed-out" 💥

Looking at the network console, I see a lot of failed network requests, and it appears to me that the DeleteWorkspace request was not serialized properly and eventually gave up:

image

@aldo-expensify
Copy link
Contributor Author

@roryabraham , when doing step 5 "Verify that workspace-employee sees:", did you sign in after the employee was invited? or was it already signed in when it was invited? I think we are not pushing the chats to users to make it appear for users that are already logged

@aldo-expensify
Copy link
Contributor Author

about step 8.ii, 8.iii, 8.iv yes, I didn't consider that part in the optimistic update, I just made the workspace disappear. Should we try to change that? not sure if it is easy or not to archive those chats/rooms in the optimistic update and then revert on fail.

@roryabraham
Copy link
Contributor

did you sign in after the employee was invited?

Yes, I signed in after the employee was invited.

I think we are not pushing the chats to users to make it appear for users that are already logged

Why not? imo we should do that, just like we would for any other new chat created.

about step 8.ii, 8.iii, 8.iv yes, I didn't consider that part in the optimistic update, I just made the workspace disappear. Should we try to change that?

Yeah, imo I think we should, since those chats are going to be archived by the action the user just took (archiving the workspace).

I think this is important for this pattern B implementation to be considered complete, because if a user tried to send messages in one of those reports, not knowing that it was going to be archived, then those chats would disappear when they came back online (unless we did something different to try and work around that, like changing the order of serialized requests in the sequential queue, which is something I don't think we should do without widespread agreement)

@roryabraham
Copy link
Contributor

Update – I think some of the bugs I listed above can be attributed to #10524

@aldo-expensify
Copy link
Contributor Author

I think we are not pushing the chats to users to make it appear for users that are already logged

Why not? imo we should do that, just like we would for any other new chat created.

I may not remember correctly, it's been a while since I tested before going on vacations... I think I saw that behaviour, but it was out of the scope of deleting workspace since that is related to creation.

I think this is important for this pattern B implementation to be considered complete, because if a user tried to send messages in one of those reports, not knowing that it was going to be archived, then those chats would disappear when they came back online

Sounds good to me, I'll investigate on adding that part to the optimistic updates.

@aldo-expensify
Copy link
Contributor Author

Reopened the GH issue to handle the missing optimistic updates

@OSBotify
Copy link
Contributor

🚀 Deployed to production by @roryabraham in version: 1.2.6-0 🚀

platform result
🤖 android 🤖 success ✅
🖥 desktop 🖥 success ✅
🍎 iOS 🍎 success ✅
🕸 web 🕸 success ✅

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.

8 participants