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 issue #1407: language in title #1413

Merged
merged 23 commits into from Oct 2, 2017
Merged

Fixes issue #1407: language in title #1413

merged 23 commits into from Oct 2, 2017

Conversation

mauditecandela
Copy link
Contributor

@@ -21,7 +21,7 @@ const Article = React.createClass({

shouldShowLanguagePrefix() {
if (!this.props.course.home_wiki) { return false; }
return this.props.article.language !== this.props.course.home_wiki.language;
return this.props.article.language !== this.props.course.home_wiki.language && null;
Copy link
Member

Choose a reason for hiding this comment

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

I'm not clear about what the && null is doing here. It looks like this would always return either false or null.

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, you are right. reworking on it right now, sorry.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@ragesoss I have doubled checked and at least in my local database, the articles are not receiving the language parameters, and that's why the behaviour was not as expected. Do you know if that happens in the production database as well?

(Wikimedia project lang is always NULL and also their articles, which was the only case the if statement was returning true - both languages are NULL).

One quickfix for the bug would be to change the if statement to include the language only if article.language !== home_wiki.language. Also I would add the home_wiki language in order not to have any problems with the already mention lack of article languages in the database.

So this line (line 38):

const languagePrefix = this.shouldShowLanguagePrefix() ? ${this.props.article.language}: : '';
would change to:
const languagePrefix = this.shouldShowLanguagePrefix() ? '' : ${this.props.course.home_wiki.language}:;

One bigger task would be to research why the articles have not languages defined in the database.

What do you think? If you agree I will do the new PR.

@ragesoss
Copy link
Member

@mauditecandela looking this over, I'm thinking that the best approach might be to have every article go through CourseUtils.formattedArticleTitle. That way we only have one place that is responsible for generating formatted article titles. With that approach, it may make sense to add another helper function to CourseUtils that takes a course object and an article object and handles the 'home_wiki' part of the current implementation in article.jsx.

A big benefit to moving it over to CourseUtils will be that it'll be easy to write unit tests for it (in test/utils/course_utils.spec.js).

@mauditecandela
Copy link
Contributor Author

I will try that out.

@mauditecandela
Copy link
Contributor Author

@ragesoss and @testa19 here it is a test. I am not 100% sure if the logic is the desirable, when testing it in my local environment it seemed fine but could be that I am missing something. Could you please have a look and give me some feedback? Thanks a lot.

@ragesoss
Copy link
Member

@mauditecandela there's another linting error that is breaking the build. If you run gulp locally, it will re-run the linter ever time you save a change so you can see any linting errors quickly. I also recommend installing an eslint plugin to your code editor, so you can see any linting errors as you're codeing.

@mauditecandela
Copy link
Contributor Author

aaaand it's green! Waiting for your feedback :) In my local machine seems to work and worked on the approach of transferring everything to course_utils.js in order to make easier to do some tests.

@ragesoss
Copy link
Member

@mauditecandela cool!

It looks like the only place that users CourseUtils.formattedArticleTitle is in assignment.jsx, and it already has an article object that will include the language and project.

So I think we should combine those into a single function that takes article and defaultWiki as arguments (which your new function does) and call it from assignment.jsx

I think formattedArticleTitle is a better name for that function. Changing the signature of formattedArticleTitle will cause the tests to break, so you'll need to adjust the tests as well. But it'll also be a good chance to test it more thoroughly and intuitively, around the idea of 'given an article on some wiki, and a default wiki, how do we want the title to be displayed'.

You can run the javascript tests locally by running jest --watch. That will rerun the tests whenever you change a js file or corresponding test.

@mauditecandela
Copy link
Contributor Author

Hi @ragesoss here my first proposal as a possible solution. As you suggested, I have merged both functions but in order to work finely, I also separated the title formatting action also from articleFromAssignment() function. I think this is more consistent, but also lead me to change different files where the article.formatted_title was expected to be available after creating the article from the assignment.

I have also noticed that the problem that appears in this test: https://travis-ci.org/WikiEducationFoundation/WikiEduDashboard/jobs/280854551 was not appearing in my local jest, do you know why?

Btw, thanks for the hint, jest is a great tool and now I love it!

I look forward your feedback :)

@ragesoss
Copy link
Member

@mauditecandela we have two different test frameworks: Jest for unit testing of Javascript, and RSpec for doing Ruby unit tests as well as browser tests. Those 'multiwiki assignments' tests are browser tests, so they don't get run by Jest. (If you are running guard, it will try to automatically run relevant tests similarly to what Jest does, but because the browser tests aren't linked to a single file, they generally don't get run unless you run them explicitly or you're running the entire test suite.)

Copy link
Member

@ragesoss ragesoss left a comment

Choose a reason for hiding this comment

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

I think this will be a lot cleaner if the signature of formattedArticleTitle changes to (article, defaultWiki), where defaultWiki is optional. The more we can have these functions work in terms of the main abstractions used throughout the system — article and wiki, in this case — the easier they will be to understand and maintain.

@@ -141,7 +141,7 @@ describe('courseUtils.articleFromTitleInput', () => {
});
});

describe('courseUtils.articleFromAssignment', () => {
describe('courseUtils.formattedArticleTitle', () => {
Copy link
Member

Choose a reason for hiding this comment

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

This is still a test of articleFromAssignment.

@@ -92,18 +92,12 @@ const CourseUtils = class {
const language = assignment.language || 'en';
const project = assignment.project || 'wikipedia';
const articleUrl = assignment.article_url || this.urlFromTitleAndWiki(assignment.article_title, language, project);
const formattedTitle = this.formattedArticleTitle(
Copy link
Member

Choose a reason for hiding this comment

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

Instead of removing this and setting formatted_title in other places every time this is called, you could do article.formatted_title = this.formattedArticleTitle(article) before the return.

If necessary, you could also make articleFromAssignment take an optional homeWiki argument to include.

In general, the more shared logic we can move into CourseUtils, the better. Isolating that logic into the shared vanilla Javascript function makes it much easier to test and maintain.

let languagePrefix = '';
if (language === undefined || language === 'en') {
if (!home || language === home.language || language === null || language === undefined || language === 'en') {
Copy link
Member

Choose a reason for hiding this comment

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

We can probably do away with the special-casing of 'en' here. Also, see if you can simplify this conditional any further.

@@ -153,8 +153,6 @@ describe('courseUtils.articleFromAssignment', () => {
expect(article.url).to.eq('https://es.wikipedia.org/wiki/Autofoto');
expect(article.title).to.eq('Autofoto');
expect(article.language).to.eq('es');
expect(article.project).to.eq('wikipedia');
Copy link
Member

Choose a reason for hiding this comment

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

This should still be true.

this.props.assignmentGroup[0].project,
article.title,
this.props.course.home_wiki);
article.formatted_title = CourseUtils.formattedArticleTitle(article);
Copy link
Member

Choose a reason for hiding this comment

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

This line seems unnecessary if articleFromAssignment does this already.

this.props.course.home_wiki);
article.formatted_title = CourseUtils.formattedArticleTitle(article);
if (!article.formatted_title) {
article.formatted_title = CourseUtils.formattedArticleTitle(this.props.assignmentGroup[0]);
Copy link
Member

Choose a reason for hiding this comment

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

Here you can do article.formatted_title = CourseUtils.formattedArticleTitle(article, this.course.home_wiki)

The fewer times we need to call assignmentGroup[0], the more understandable this code will be.

language,
project,
language: language,
project: project,
Copy link
Member

Choose a reason for hiding this comment

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

This is fine, but means the same thing as what was there before, which is es2015 shorthand notation: { foo } is the same as { foo: foo }.

@mauditecandela
Copy link
Contributor Author

I have already reduced the code as you suggested the only problems that I see are:

  • Any formatted title created from articleFromAssignment is not showing any language or project. I think it's because they are not defined yet. I think this was the behaviour that I saw at the beginning, can you confirm? Any other suggestions?
  • There's a test that keeps failing, but I will try to fix it tomorrow :)
    Any other feedback is very welcome, of course.

@ragesoss
Copy link
Member

@mauditecandela I think the way to solve both of these is to pass course.home_wiki articleFromAssignment, and set the language and project from that if it is not provided by the assignment argument.

@mauditecandela
Copy link
Contributor Author

mauditecandela commented Sep 29, 2017

This is passes all tests (finally!) and adds the defaultWiki to articleFromAssignment. I also removed te unneeded part of the object.

@@ -241,7 +241,8 @@ const AssignButton = React.createClass({
let removeButton;
let articleLink;
ass.course_id = this.props.course_id;
const article = CourseUtils.articleFromAssignment(ass);
const article = CourseUtils.articleFromAssignment(ass, this.props.course.home_wiki);
if (!article.formatted_title) { CourseUtils.formattedArticleTitle(article, this.props.course.home_wiki); }
Copy link
Member

Choose a reason for hiding this comment

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

Is this necessary? Unlike in assignment.jsx, this article object is always generated by CourseUtils.articleFromAssignment, so it should always have a formatted_title.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

true!

let languagePrefix = '';
if (language === undefined || language === 'en') {
if (defaultWiki === undefined || article.language === defaultWiki.language || article.language === null || article.language === undefined) {
Copy link
Member

Choose a reason for hiding this comment

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

These can be simplified somewhat, I think. Instead of checking article.language and defaultWiki against multiple precise conditions, we can just check for falsiness: !defaultWiki and !article.language.

@ragesoss
Copy link
Member

@mauditecandela this is almost there. I really like how much this simplifies both article.jsx and assignment.jsx.

What remains:

  • Simplify the logic of the formattedArticleTitle function as much as possible.
  • Update the course_utils spec to test the various possibilities more thoroughly.

@mauditecandela
Copy link
Contributor Author

Thanks a lot for all the guidance and the comments @ragesoss Here it is the new version. I added some tests and simplified the logic are formattedArticleTitle. Let me know what you think :)

@ragesoss
Copy link
Member

@mauditecandela the tests still have some room for improvement, to reflect the different situations where article titles get displayed. It looks like everywhere except for components/students/assign_cell.jsx that calls articleFromAssignment() now passes course.home_wiki, but the tests don't reflect that; no defaultWiki is included in the tests for that function. The home_wiki can be added to the call in AssignCell, and the tests should include it. In particular, that test was trying to make sure that when you assign an article from Spanish Wikipedia in the context of an English Wikipedia course, that it shows the language prefix, and that project correctly to Wikipedia.

For the tests of formattedArticleTitle, similarly, it looks like we're going to be able to use it always with the defaultWiki included, so the tests should reflect that, but they should test all the main possible situations: when the article is on the same wiki as the course; when the article is the same project but different language; when the article is same language but different project; when the article is different langauge and different project; and when the article is a different project that doesn't have a language (ie, Wikidata).

@mauditecandela
Copy link
Contributor Author

@ragesoss you were right, I was too tired yesterday and today I saw that the tests were far from accurate. I corrected them, please let me know what you think. I am excited! I enjoyed very much working on this. :)

expect(article.formatted_title).to.eq('wikidata:Judith Butler');
});

it('returns true for a weeks array with trainings', () => {
Copy link
Member

Choose a reason for hiding this comment

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

Duplicate

@ragesoss
Copy link
Member

I am excited! I enjoyed very much working on this. :)

:-)

Please add the course home_wiki to the AssignCell component, and remove the duplicated hasTrainings() test. I'll test it out on Monday to make sure that everything is behaving as expected, and if so, it should be good to merge.

@mauditecandela
Copy link
Contributor Author

Done!!!

@ragesoss ragesoss merged commit f584bfc into WikiEducationFoundation:master Oct 2, 2017
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

2 participants