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

Update script_level URLs from /stage to /lessons and /puzzle to /levels #38802

Merged
merged 42 commits into from Apr 20, 2021

Conversation

dmcavoy
Copy link
Contributor

@dmcavoy dmcavoy commented Jan 29, 2021

Proposal Of URL Changes

As we bring content over from CB to LB we have been considering how to improve our URL scheme to better support our curriculum model. The new lesson plans which have been brought over are going to live at /s/<script name and year>/lesson/<relative_position>. However current the levels that will be in these lessons are at /s/<script name and year>/stage/<relative_position>/puzzle/<position>. In order to make our URLs more consistent we would like to move the levels to be at /s/<script name and year>/lessons/<relative_position>/levels/<position>.

Summary

  • Levels in lessons that are not lockable or have a lesson plan will move from .../stage/... to .../lessons/... and .../puzzle/... to .../levels/...

Overview of Code Changes

The core of the change in this PR is in routes.rb. That is where the updates to the script_level routes can be found as well as the new redirects that will redirect old URLs to the new URL.

0cdd2aa creates a helper method so that level keys for translations stay on the old URLs for now until foundations has a chance to move them over to the new system.

All of the other changes were to get tests passing. There are A LOT of UI tests where we are updating the URL that we are navigating to.

Links

Testing story

  • Added a couple new tests for the translations helper method
  • Updated URLs in UI tests to the new URLs to get tests passing
  • Other tests updates in order to get tests to pass

We have a lot of existing tests covering script levels especially in script_levels_controller_test.rb so I am relying on those for unit testing. We will also be doing 2 bug bashes of this before launching.

Reviewer Checklist:

  • Tests provide adequate coverage
  • Privacy and Security impacts have been assessed
  • Code is well-commented
  • New features are translatable or updates will not break translations
  • Relevant documentation has been added or updated
  • User impact is well-understood and desirable
  • Pull Request is labeled appropriately
  • Follow-up work items (including potential tech debt) are tracked and linked

@dmcavoy dmcavoy requested a review from a team as a code owner January 29, 2021 20:25
@dmcavoy dmcavoy removed the request for review from a team February 3, 2021 02:57
dashboard/config/routes.rb Outdated Show resolved Hide resolved
dashboard/config/routes.rb Outdated Show resolved Hide resolved
@dmcavoy dmcavoy changed the title Update script level url Update script_level URLs from /stage to /lesson Feb 3, 2021
@dmcavoy dmcavoy marked this pull request as draft February 9, 2021 04:06
@dmcavoy dmcavoy changed the title Update script_level URLs from /stage to /lesson Update script_level URLs from /stage to /lessons and /puzzle to /levels Mar 30, 2021
@dmcavoy dmcavoy requested a review from a team April 7, 2021 01:59
@dmcavoy
Copy link
Contributor Author

dmcavoy commented Apr 7, 2021

Copy link
Contributor

@jamescodeorg jamescodeorg left a comment

Choose a reason for hiding this comment

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

I don't really understand what's going on with the translation stuff but the core route changes look good to me and I'm assuming drone will catch any issues with the tests.

Thank you so much for doing this! This is difficult, tedious work and this is a huge step forward towards unifying our urls and getting rid of the 'stage' terminology in our codebase.

## TODO: Once we move levels over to /lessons as well combine the routing rules
resources :lessons, only: [:show], param: 'position' do
# /s/xxx/lessons/yyy
resources :lessons, only: [:show], path: "/lessons", param: 'position', format: false do
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious, is it necessary to specify path here (since it matches the resource name)?

Also, I noticed that we also have edit and update actions defined for lessons above on 297. Is it intentional that these are separate? (I could imagine us wanting to keep those closer to the other edit/update entries.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try removing path since we are no longer using stage you are probably right its no longer needed. I'll also take a look at the other lesson entries to see if I can bring them closer together

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Oh I know why I left the other lessons stuff separate. Its because when you are editing or updating you are not using the nested route inside the script like we do for showing.

Copy link
Member

@davidsbailey davidsbailey left a comment

Choose a reason for hiding this comment

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

Nice job pulling this all together, Dani! I have some comments around testing and caching.

I think it will also be important to think about "deployment strategy", i.e. is it safe to deploy this entire PR at once, or is there some place where we need to point people to a new route before taking away an old one. since you are replacing the old routes with redirects, I think we are generally good there. Just thought I'd mention this in case it gives other reviewers any ideas.

dashboard/test/integration/caching_test.rb Show resolved Hide resolved
@@ -41,7 +41,7 @@ class HttpCache
oceans
).map do |script_name|
# Most scripts use the default route pattern.
[script_name, "/s/#{script_name}/stage/*"]
[script_name, "/s/#{script_name}/lessons/*"]
Copy link
Member

Choose a reason for hiding this comment

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

we should consider whether we want to cache requests for the original /s/.../stage/... paths. @sureshc , any ideas how we can figure out if more complex patterns are allowed here other than a trailing wildcard? we'd ideally want something like /s/[a-z0-9-]+/stage/*.

I think this might be https://docs.aws.amazon.com/cloudfront/latest/APIReference/API_CacheBehavior.html --> PathPattern, in which case perhaps we could do /s/*/stage/*/puzzle/*. However, I'm not sure if (1) those are the right docs or (2) if we use this same config somewhere else outside of cloudfront.

Copy link
Member

Choose a reason for hiding this comment

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

Suresh provided some additional context in slack:

Suresh (he/him):lightning: 6 hours ago
I believe so. Here’s where we generate the cache behavior CloudFormation template logic

def self.cache_behavior(behavior_config, path=nil)

Suresh (he/him):lightning: 6 hours ago
I always start with the CloudFormation template reference for a particular AWS service https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html

I think this means we could update http_cache.rb to filter on /s/*/stage/*/puzzle/* to maximize the caching efficiency of those pages.

I am going to suggest that we try to do this in a follow-up task. this PR is already quite large and complex, and I don't think we will suffer any irreversible consequences by failing to cache these responses for a short period of time.

Copy link
Contributor Author

@dmcavoy dmcavoy Apr 16, 2021

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

@wjordan @sureshc for any input on caching

get '/s/csp6-2020/lockable/1(*all)', to: redirect(path: '/s/csp6-2020/lessons/6%{all}')
get '/s/csp7-2020/lockable/1(*all)', to: redirect(path: '/s/csp7-2020/lessons/11%{all}')
get '/s/csp9-2020/lockable/1(*all)', to: redirect(path: '/s/csp9-2020/lessons/9%{all}')
get '/s/csp10-2020/lockable/1(*all)', to: redirect(path: '/s/csp10-2020/lessons/14%{all}')
Copy link
Member

Choose a reason for hiding this comment

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

we should consider whether these redirect requests should be cached. they should be easy enough to add to http_cache.rb, so that's what I would recommend. this could be done in a separate PR after this one. better to do after than before, since this PR changes the redirect destination, so might as well avoid ever telling browsers to cache the old value.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Copy link
Member

Choose a reason for hiding this comment

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

these redirects use status code 301, which some browsers cache indefinitely. I think we are good here, but here is me thinking aloud through a couple scenarios:

  1. the redirect from /s/csp1-2020/lockable/2/puzzle/1 to /s/csp1-2020/stage/14/puzzle/1 may be cached by some browsers. the other routes you are adding in this PR will then redirect from /s/csp1-2020/stage/14/puzzle/1 to /s/csp1-2020/lessons/14/levels/1. this seems correct.

  2. if someone hits /s/csp1-2020/lockable/2/levels/1, it would be bad if the old redirect were cached, because that would send them to /s/csp1-2020/stage/14/levels/1, which would 404, because stage + levels is never handled. It seems very unlikely for someone to have this redirect cached though, because they would only be able to cache the response to an individual request, not the entire pattern of /s/csp1-2020/lockable/2(*all), and there is no point in time at which our servers should ever have sent anyone to /s/csp1-2020/lockable/2/levels/1. This is because we stopped sending people anywhere within /s/csp1-2020/lockable/2/ in Send users to new CSP 20-21 URLs for lockable lessons with lesson plans and redirect old URL #39128, and we won't be sending anyone to /levels/ urls until after this PR.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks for thinking this through!

Copy link
Member

Choose a reason for hiding this comment

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

@wjordan @sureshc again for any input on caching the "lockable" routes

dashboard/app/helpers/view_options_helper.rb Show resolved Hide resolved
dashboard/test/integration/redirects_test.rb Show resolved Hide resolved
@dmcavoy
Copy link
Contributor Author

dmcavoy commented Apr 13, 2021

@daynew @sureshc Just wanted to check in. Do you think you will have a chance to look at this PR this sprint?

Copy link
Member

@davidsbailey davidsbailey left a comment

Choose a reason for hiding this comment

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

Great work Dani! I am nervous about this change, but I've checked all the things i can think of to check and I can't think of any other precautions to take. LGTM!

@@ -41,7 +41,7 @@ class HttpCache
oceans
).map do |script_name|
# Most scripts use the default route pattern.
[script_name, "/s/#{script_name}/stage/*"]
[script_name, "/s/#{script_name}/lessons/*"]
Copy link
Member

Choose a reason for hiding this comment

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

Suresh provided some additional context in slack:

Suresh (he/him):lightning: 6 hours ago
I believe so. Here’s where we generate the cache behavior CloudFormation template logic

def self.cache_behavior(behavior_config, path=nil)

Suresh (he/him):lightning: 6 hours ago
I always start with the CloudFormation template reference for a particular AWS service https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-properties-cloudfront-distribution-cachebehavior.html

I think this means we could update http_cache.rb to filter on /s/*/stage/*/puzzle/* to maximize the caching efficiency of those pages.

I am going to suggest that we try to do this in a follow-up task. this PR is already quite large and complex, and I don't think we will suffer any irreversible consequences by failing to cache these responses for a short period of time.

dashboard/test/integration/redirects_test.rb Show resolved Hide resolved
get '/s/csp6-2020/lockable/1(*all)', to: redirect(path: '/s/csp6-2020/lessons/6%{all}')
get '/s/csp7-2020/lockable/1(*all)', to: redirect(path: '/s/csp7-2020/lessons/11%{all}')
get '/s/csp9-2020/lockable/1(*all)', to: redirect(path: '/s/csp9-2020/lessons/9%{all}')
get '/s/csp10-2020/lockable/1(*all)', to: redirect(path: '/s/csp10-2020/lessons/14%{all}')
Copy link
Member

Choose a reason for hiding this comment

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

these redirects use status code 301, which some browsers cache indefinitely. I think we are good here, but here is me thinking aloud through a couple scenarios:

  1. the redirect from /s/csp1-2020/lockable/2/puzzle/1 to /s/csp1-2020/stage/14/puzzle/1 may be cached by some browsers. the other routes you are adding in this PR will then redirect from /s/csp1-2020/stage/14/puzzle/1 to /s/csp1-2020/lessons/14/levels/1. this seems correct.

  2. if someone hits /s/csp1-2020/lockable/2/levels/1, it would be bad if the old redirect were cached, because that would send them to /s/csp1-2020/stage/14/levels/1, which would 404, because stage + levels is never handled. It seems very unlikely for someone to have this redirect cached though, because they would only be able to cache the response to an individual request, not the entire pattern of /s/csp1-2020/lockable/2(*all), and there is no point in time at which our servers should ever have sent anyone to /s/csp1-2020/lockable/2/levels/1. This is because we stopped sending people anywhere within /s/csp1-2020/lockable/2/ in Send users to new CSP 20-21 URLs for lockable lessons with lesson plans and redirect old URL #39128, and we won't be sending anyone to /levels/ urls until after this PR.

@dmcavoy dmcavoy requested review from wjordan and removed request for sureshc April 16, 2021 16:38

# This is a a temporary method to help with moving translations onto the new level urls. To start this will
# keep translations on the old URL until foundations can do the work to bring them over to the new url
def build_script_level_path_for_translations(script_level)
Copy link
Member

Choose a reason for hiding this comment

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

I noticed this doesn't have the exact same code as the old build_script_level_path. Is that intentional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes it is. I noticed that the translations call to build_script_level_path was not using the second paramater param and that means it would never hit certain cases. So I just kept the cases that it would hit

@dmcavoy
Copy link
Contributor Author

dmcavoy commented Apr 19, 2021

@daynew @davidsbailey @wjordan @sureshc @jamescodeorg I'm planning to ship this change this week once PM gives the thumbs up on one last thing. Is there anything from you all that you would like me to check before merging? Any other considerations here?

Copy link
Member

@davidsbailey davidsbailey left a comment

Choose a reason for hiding this comment

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

LGTM! I've tagged Suresh and Will in places related to caching. If they don't have time to look this week, then it should be ok to proceed, and we can address any concerns in follow-up work.

@@ -41,7 +41,7 @@ class HttpCache
oceans
).map do |script_name|
# Most scripts use the default route pattern.
[script_name, "/s/#{script_name}/stage/*"]
[script_name, "/s/#{script_name}/lessons/*"]
Copy link
Member

Choose a reason for hiding this comment

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

@wjordan @sureshc for any input on caching

get '/s/csp6-2020/lockable/1(*all)', to: redirect(path: '/s/csp6-2020/lessons/6%{all}')
get '/s/csp7-2020/lockable/1(*all)', to: redirect(path: '/s/csp7-2020/lessons/11%{all}')
get '/s/csp9-2020/lockable/1(*all)', to: redirect(path: '/s/csp9-2020/lessons/9%{all}')
get '/s/csp10-2020/lockable/1(*all)', to: redirect(path: '/s/csp10-2020/lessons/14%{all}')
Copy link
Member

Choose a reason for hiding this comment

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

@wjordan @sureshc again for any input on caching the "lockable" routes

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.

None yet

4 participants