-
Notifications
You must be signed in to change notification settings - Fork 3
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
Customizable URLs for studio #1316
Conversation
9769089
to
ab1332c
Compare
Codecov Report
@@ Coverage Diff @@
## master #1316 +/- ##
==========================================
+ Coverage 89.06% 89.10% +0.04%
==========================================
Files 231 232 +1
Lines 9557 9687 +130
Branches 1778 1827 +49
==========================================
+ Hits 8512 8632 +120
- Misses 928 930 +2
- Partials 117 125 +8
Continue to review full report at Codecov.
|
f21f4e5
to
058f706
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will be great :) I'm still doing the manual testing but have looked through most of the code except the pipeline stuff. I left a few specific comments largey around ts stuff on the frontend. Small, but probably worth addressing since they're low effort.
Frontend bug I noticed...:
- Edit and save metadata form
- click publish ... publishing form is using old metadata values.
websites/serializers.py
Outdated
@@ -519,7 +567,7 @@ class Meta: | |||
class WebsiteContentCreateSerializer( | |||
serializers.ModelSerializer, RequestUserSerializerMixin | |||
): | |||
"""Serializer which creates a new WebsiteContent""" | |||
"""Serializer mixin which validates that urls are unique""" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this docstring correct?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope, pasted in the wrong place
onSubmit: ( | ||
values: any, | ||
formikHelpers: FormikHelpers<any> | ||
) => void | Promise<any> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
onSubmit: ( | |
values: any, | |
formikHelpers: FormikHelpers<any> | |
) => void | Promise<any> | |
onSubmit: ( | |
values: SiteFormValues, | |
formikHelpers: FormikHelpers< SiteFormValues > | |
) => void |
void
is good enough for the return value; nothing should be using that value.
.trim() | ||
.required() | ||
.matches( | ||
/^[a-zA-Z0-9\-._]*$/, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is probably a question for Ferdi, but we may want to pick either dash or underscore and not allow both.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally don't like underscores in the url but I dont think we should disallow them .
option | ||
}: Props): JSX.Element | null => { | ||
const initialValues: SiteFormValues = { | ||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here and elsewhere, we should use @ts-expect-error
for suppressing errors. That directive will throw an error if used unnecessarily. (I've encountered a fair number of unnecessary @ts-ignore
in our code; @ts-expect-error
is somewhat newer, so may not have existed when studio started.).
website, | ||
disabled, | ||
option | ||
}: Props): JSX.Element | null => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This component never returns null
.
My personal preference is to use the React.FC
helper to declare functional component types...export const PublishForm: React.FC<Props> = ({...whateverProps}) => {}
, then React takes care of the return type.
expect(error).toBeInstanceOf(ValidationError) | ||
// @ts-ignore |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an assertIsInstanceOf
helper in test_util
if you want to do this without the @ts-ignore
. assertIsInstanceOf
will narrow the type (expect...toBeInstanceOf...
does not narrow the type).
;[null, "courses/5.2-my-course"].forEach(urlPath => { | ||
it(`initialValue for url_path should be based on website ${ | ||
urlPath ? "url_path" : "url_suggestion" | ||
}`, () => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can use it.each([...])("Description...", option => {})
here to reduce nesting / use jest conventions. https://jestjs.io/docs/api#describeeachtablename-fn-timeout
If the array is an array of objects, you can access them by $name
in the description string... My personal preference is to hardcode the title formatting like
it.each([
{ urlPath: null, basedOn: "url_suggestion" },
{ urlPath: "courses/5.2-my-course", basedOn: "url_path" }
]).only("initialValue ... based on website $basedOn", ({ urlPath }) => {...})
@@ -0,0 +1,130 @@ | |||
import React from "react" | |||
import sinon, { SinonStub } from "sinon" | |||
import { shallow } from "enzyme" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a general comment, not worth addressing right now.
Opinion: For new tests, we should avoid enzyme and shallow rendering. Enzyme does only supports React 16 and below, which is two major versions behind current. See #1275 and or https://github.com/mitodl/hq/discussions/17
for section in re.findall(r"(\[.+?\])+", site_config.site_url_format) or []: | ||
section_type, section_field = re.sub(r"[\[\]]+", "", section).split(":") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we changed the config format to
{sitemetadata.primary_course_number}-{sitemetadata.course_title}-{sitemetadata.term}-{sitemetadata.year}
We might be able to do site_config.site_url_format.format(sitemetadata=metadata)
.
Do you think this would be worth doing? We'd need a version of the metadata dict that supports attribute access, but we would get formatting and some validation builtin (e.g., .format
raises KeyError if keys are missing).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice idea! But it doesn't quite work as intended if any of the metadata fields haven't been filled out yet. For example, when I try it on a site with fields for primary_course_number
and title
but no term
and year
, I get:
slugify(site_config.site_url_format.format(**metadata).replace(".", "-"))
>2.18-time-travel-101-abc-
But what I want is placeholders for the missing values like 2.18-time-travel-101-abc-{term}-{year}
@mbertrand I tried the pipelines / renaming etc and everything worked as expected: URLs got updated in github when I changed the course url 👍 Do you think the frontend form using outdated metadata is a blocking issue? Probably not? |
I think I know how to fix that, will give it a shot. |
I'm not sure I could point out anything from a technical standpoint that @ChristopherChudzicki hasn't already mentioned, but for what it's worth I experienced the same behavior where updating my metadata wasn't reflected on the URL in the publish drawer until I refreshed the page. One UI thing that I noticed that I didn't see pointed out is that with the new text field in the publish drawer, it seems to open super wide: Do we maybe want to restrict the width on this? I tried publishing my test course, which already existed, and I noticed that the |
I made the publish drawer deliberately wide if the site hasn't been published to production yet, because the If you're seeing |
The suggested url format in the publish drawer should now be updated after a metadata change. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Pre-Flight checklist
app.json
What are the relevant tickets?
Closes #1336
What's this PR do?
url_path
field toWebsite
. The migration should prepopulate it with the same value asWebsite.name
for all sites that have already been published to production.url_path
can be sent in the request body to set the field's value. The serializer should allow the field value to change as long as the site hasn't been published to production yet and the value is valid. If the value is changed, allWebsiteContent
objects with populatedfile
values for the site will have their synced_checksums reset so they will be resynced to github with the updated path.file
values (based onurl_path
) to the backend (git) and vice versa.site-url-format
field in site config to suggest a pattern for this field to the user on the front end.How should this be manually tested?
docker-compose --profile concourse up
manage.py upsert_mass_build_pipeline
andbackpopulate_pipelines
, they should both succeed.publish_date
, the drawer should look about the same and work the same.publish_date
, you should see a URL field with a suggested path, any existing metadata values matching the pattern should be present. Enter a valid value and click 'Publish' to draft, check to see that theurl_path
is updated and the pipeline is triggered (it will fail, that's ok).file
value that contains the site's url path.Where should the reviewer start?
https://github.com/mitodl/hq/discussions/1
Screenshots (if appropriate)
An unpublished site without any user-supplied url path so far:
An unpublished site with a previously chosen url (still editable):
A published site (no longer editable):