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

Add directives to modify attributes and include feature flags where needed #6341

Merged
merged 5 commits into from
May 3, 2023

Conversation

groszewn
Copy link
Contributor

Updates individual HTML elements to include client feature flags as query parameters on their src attributes through the use of a directive.

Validated via a local tensorboard that the attributes generated from these directives include the client feature flags as query parameters.

@groszewn groszewn requested a review from bmd3k April 21, 2023 18:17
@groszewn groszewn marked this pull request as ready for review April 21, 2023 18:17
@groszewn groszewn force-pushed the client_feature_flags branch 6 times, most recently from 206e409 to 78afa74 Compare May 1, 2023 12:35
@groszewn
Copy link
Contributor Author

groszewn commented May 1, 2023

@bmd3k thanks for the offline help, tests should be passing now with the singular directive.

@groszewn groszewn requested a review from bmd3k May 2, 2023 11:05
declarations: [FeatureFlagDirective],
exports: [FeatureFlagDirective],
})
export class FeatureFlagDirectiveModule {}
Copy link
Contributor

Choose a reason for hiding this comment

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

Usually we keep the NgModule in a seperate file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Updated.

export class FeatureFlagDirective {
@HostBinding('attr.href') hrefAttr: string | undefined = undefined;
@HostBinding('attr.src') srcAttr: string | undefined = undefined;
@Input() includeFeatureFlags: boolean = true;
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a little confusing.

[includeFeatureFlags]="false", for example, won't actually have any impact on the logic. It will behave exactly the same as though [includeFeatureFlags] is unset or [includeFeatureFlags]="true".

I think that's fine for now (and maybe forever) but it would be good to acknowledge that with a comment.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Left a comment.

@@ -0,0 +1,136 @@
/* Copyright 2022 The TensorFlow Authors. All Rights Reserved.
Copy link
Contributor

Choose a reason for hiding this comment

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

2023 (and elsewhere)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

class TestableHrefComponent {
@ViewChild(
TestComponent
) /* using viewChild we get access to the TestComponent which is a child of TestHostComponent */
Copy link
Contributor

Choose a reason for hiding this comment

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

IMO these comments are oddly located and should appear before the entire statement that defines and annotates the variable. (so this would move to L47, for example, and the ViewChild annotation would move to L48.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer relevant/necessary, simplified the test setup.

class TestableHrefComponent {
@ViewChild(
TestComponent
) /* using viewChild we get access to the TestComponent which is a child of TestHostComponent */
Copy link
Contributor

Choose a reason for hiding this comment

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

Nit: Comments are statements or sentences to the best of our ability. Specifically this means you Capitalize the first letter in the comment and you put some punctuation at the end of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ack, this setup has been simplified so we no longer have this.


it('injects feature flags in <img> tags if any are set', fakeAsync(() => {
store.overrideSelector(getFeatureFlagsToSendToServer, {inColab: true});
const anchorStr = createImgComponent('https://abc.def');
Copy link
Contributor

Choose a reason for hiding this comment

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

You should also test the case where there are already query parameters since that is a case handled in your class.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

selector: 'test',
template: `<p>{{ value }}</p>`,
})
export class TestComponent {
Copy link
Contributor

Choose a reason for hiding this comment

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

I don't understand why TestComponent exists. Can it be removed from the tests?

L94 has:

const component = hostComponent.testComponent;

But nothing is done with component.

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 setup was necessary with the initial implementation (since ngOnChanges was used, but detectChanges wasn't invoking the lifecycle hook). I've simplified the setup to remove this.

class TestableHrefComponent {
@ViewChild(
TestComponent
) /* using viewChild we get access to the TestComponent which is a child of TestHostComponent */
Copy link
Contributor

Choose a reason for hiding this comment

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

What is TestHostComponent?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No longer needed, but that was a copy/paste error.


it('leaves <a> tags unmodified if no feature flags are set', fakeAsync(() => {
const anchorStr = createHrefComponent('https://abc.def');
expect(anchorStr.attributes['href']).toBe('https://abc.def');
Copy link
Contributor

Choose a reason for hiding this comment

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

For what it's worth, merging the <a> and <img> versions of this directive into one was meant to limit some of this duplication in tests. Assuming you thoroughly test <img> tags then I think you could get away with just a single test for <a> tags - mostly like the one currently on line 124.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done.

it('leaves <a> tags unmodified if no feature flags are set', fakeAsync(() => {
const anchorStr = createHrefComponent('https://abc.def');
expect(anchorStr.attributes['href']).toBe('https://abc.def');
}));
Copy link
Contributor

Choose a reason for hiding this comment

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

Do you mind adding tests where the a or img tag does not contain [includeFeatureFlags] attribute?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Added.

…ecessary

Updates individual HTML elements to include client feature flags as
query parameters on their src attributes through the use of a directive.

Validated via a local tensorboard that the attributes generated from these
directives include the client feature flags as query parameters.
@groszewn groszewn merged commit b57ca2d into tensorflow:master May 3, 2023
@groszewn groszewn deleted the client_feature_flags branch May 3, 2023 12:04
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.

2 participants