-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
Address Microsite PR feedback - separate out middleware from microsite logic, shor... #2553
Conversation
@nedbat @jzoldak @singingwolfboy - I believe this addresses your remaining concerns on the original PR. @sefk just cc:'ing you in as well in case you want to do a regression test I need to do some more manually testing, but I thought I'd get the code review started. |
@antoviaque you'd be interested in this as well since we are using Microsites for some of our projects. I think the only configuration delta here is that we need to now set a FEATURES['USE_MICROSITES'] = True. Worst case, I can grandfather in not setting this feature flag and inferring it from if one had set the MICROSITE_CONFIGURATION configuration dictionary. |
_microsite_configuration_threadlocal.data = {} | ||
|
||
|
||
class Microsite(object): |
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 you have a class that's never instantiated and consists entirely of classmethods, why not just make them functions at the module level?
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.
That might be the .NET coder in me coming out :-)
I'm happy to change it, but - stylistically speaking - I do like to do this kind of "namespacing". Is there something particularly "un-pythonic" about that pattern?
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.
Namespacing can and should be done using files/modules, not with classes. If a function can be decoupled from a class definition, it should be -- attaching it to a class adds unnecessary complexity, and often makes unit testing more difficult.
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.
Thanks.
well, unfortunately, I'm getting conflicting feedback on this feature. On one hand I've been asked to make the function names shorter (from @nedbat) , e.g. get_microsite_configuration_value() -> get_value(). However, if I make these straight up classless methods, then those names become pretty ambiguous and so the longer name (get_microsite_configuration_value()) makes more sense.
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.
The module already provides a namespace: microsite.get_value()
You can import microsite rather than Microsite.
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.
ah, gotcha.
Thanks
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 agree -- if you decouple the functions from the class, then the longer names make sense. At the same time, I think that you could dramatically simplify the data model, and simply expose the microsite configuration dict, so that people could import that and use standard Python indexing syntax (or standard dict methods like get()
) to achieve the same result, which could make sense as well. Check out the other pull request I did for this feature to get a feel for what I'm referring to.
Thanks for the feedback. It might take a day or two to address. |
|
||
for key in settings.MICROSITE_CONFIGURATION.keys(): | ||
subdomain = settings.MICROSITE_CONFIGURATION[key]['domain_prefix'] | ||
if domain.startswith(subdomain): |
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.
Could you add support for a 'default' configuration, which would apply a given microsite configuration when it doesn't match any subdomain? It would make it easier to use it to skin instance with only one skin, and would allow support for domains without a subdomain, like edx.org
.
@chrisndodge Sounds good to add |
@nedbat @davestgermain @singingwolfboy @antoviaque - responded to your feedback. Waiting for build results. One note, we still have a "hack" for detecting when on Edge and showing a different homepage. The only other approach I could think of is make Edge be a "microsite" just in terms of the subdomain matching (but not define any overrides) but that would require config changes to be pushed through as well otherwise we'd loose the Edge homepage. @sefk keeping you in the loop in case you all want to do any regression tests or have any other feedback. |
This PR replaces #2061 |
@@ -76,6 +76,9 @@ | |||
|
|||
# Allow editing of short description in course settings in cms | |||
'EDITABLE_SHORT_DESCRIPTION': True, | |||
|
|||
# Turn on/off Microsites feature | |||
'USE_MICROSITES': False, |
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.
Nitpick: I'd prefer to refer to settings.FEATURES['MICROSITES']
rather than settings.FEATURES['USE_MICROSITES']
. It's not a big deal, though -- I think "USE" is unnecessary, but if you think the "USE" makes things clearer somehow, then I'm OK with it.
I'll try to review tonight, tomorrow morning: 1st high level comment, can I get you to incorporate |
@jbau done. And of course there's now a merge conflict on this PR :-) |
@chrisndodge well, at least tests passed =) |
OIC. You merged #2534 into master. I had thought you would merged it into this PR, but no matter. |
OK. This looks fine to me, once the merge conflict and other comments are resolved. |
OK, will rebase and squash commits. I'll try to squeeze in @nedbat and @singingwolfboy's small comment. |
@@ -0,0 +1,26 @@ | |||
""" |
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.
Please rename this to something like: test_logic.py, and move ../test_microsites.py file into the tests directory also.
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'd like to move test_microsites.py but it's dependent on LMS serving up HTML, so shouldn't it remain in lms tests?
@singingwolfboy @nedbat @antoviaque care to do another final pass? I'd like to merge this in tomorrow AM. |
@jzoldak ^ |
"email_from_address": "test_microsite@edx.org", | ||
"payment_support_email": "test_microsite@edx.org", | ||
"ENABLE_MKTG_SITE": False, | ||
"SITE_NAME": "test_microsite.localhost", |
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.
That made me realize that different options have different cases - I understand where this comes from, and this is not a blocker, but while we are doing changes, it might be worth capitalizing all options for consistency.
microsites_root=COMMON_ROOT / "test" / 'test_microsites' | ||
) | ||
MICROSITE_ROOT_DIR = COMMON_ROOT / 'test' / 'test_microsites' | ||
FEATURES['USE_MICROSITES'] = True |
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.
That should be enabled by your tests during setup instead of overriding the default for all tests, no?
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 thought it'd be good to be global to make sure that we exercise non-microsite renderings through the existing tests. If we localize this FEATURE flag to just the microsite tests, then we don't get test execution which simulate what it'll be like when we have this FEATURE flag set in product, but the requests don't actually go through them.
OK, to skip this recommendation?
Besides the last two remarks, LGTM. A lot of cleanup, thanks for this! |
|
||
# now test when we call in a value Microsite ORG, note this is defined in test.py configuration | ||
value = get_value_for_org("TestMicrositeX", "university", "default_value") | ||
self.assertEquals(value, "test_microsite") |
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.
Please also write tests that cover (at a minimum) get_template_path
, get_all_orgs
, get_value_for_org
, and set_by_domain
. It would also be nice if you could write a test that works more at the integration level: use the Django test client to get the HTML for a page that should change depending on the active microsite, assert that some microsite-specific things are present in that HTML, assert that some things that they replace are not present, and assert that some things specific to a different microsite in the configuration are not present. Also assert that you can hit that same page without the microsite prefix in the URL, and that the original page is returned, without the microsite customizations.
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.
We do have integration level test which pass in a microsite domain and inspects the HTML output. It's in lms/djangoapps/courseware/test_microsite.py, or something like that - I don't have the source code in front of me right now.
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.
Ah, OK. Never mind, then. :)
@singingwolfboy addressed a number of your comments. With regards to test coverage, we have coverage on a number of your suggestions via the LMS integration tests. I believe we are at 95% coverage right now for this PR Can I get two thumbs up? |
@@ -20,13 +20,15 @@ | |||
|
|||
<% | |||
if self.theme_enabled(): | |||
google_analytics_file = u'../' + MicrositeConfiguration.get_microsite_configuration_value('google_analytics_file', 'theme-google-analytics.html') | |||
google_analytics_file = u'../{ga}'.format( | |||
ga = microsite.get_value('google_analytics_file', 'theme-google-analytics.html') |
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.
Nitpick: pep8 doesn't like the whitespace on either side of the =
, because it's for keyword arguments to a function. Looks like the Diff Quality tool isn't catching it because this is Python embedded in a Mako template.
Still needs some comments around calling Thanks for doing this! |
@jbau can I get thumbs up from you as well as the "second +1"? You implicitly signed off up above, but it'd be nice to formalize it. Thank you. |
👍 |
👍, but rebase first =) |
@antoviaque this is getting merged now. This is just a reminder that we need to add the FEATURE flag to the any Customer-specific configuration deploys. Thank you. |
Address Microsite PR feedback - separate out middleware from microsite logic, shor...
Release 2018-2Q (201804-201806)
...ten up names, etc.