Skip to content

Commit a5a771f

Browse files
committed
perf(login-fire-social): use paper-social-buton and add tests
Before this commit the `login-fire-social` element was using the `login-fire-button` element. This one was embedded behaviors for i18n and authentication. So, when the login-fire-social was displaying 5 buttons, the behaviors for localize texts and the behaviors for sign-in/up was imported 5 times. Now, using the `paper-social-button` (that does not include behavior at all) the `login-fire-social` element is lighter, simpler to understand and maintain. This commit also adds unit test suites.
1 parent f52a8f4 commit a5a771f

File tree

3 files changed

+181
-65
lines changed

3 files changed

+181
-65
lines changed

demo/login-fire-social.html

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,7 @@ <h3>Signing Out</h3>
189189
<script>
190190
function signout() {
191191
const demoSnippet = document.getElementById('signing-out-demo');
192-
// NOTE: the login-fire-social element is outside of the demo-snippet's shadow root.
193-
demoSnippet.querySelector('login-fire-social').$$('login-fire-button').signOut();
194-
// You can also use:
195-
// demoSnippet.querySelector('login-fire-social').signOut();
192+
demoSnippet.querySelector('login-fire-social').signOut();
196193
}
197194
</script>
198195
</template>

login-fire-social.html

Lines changed: 58 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,10 @@
55
LICENSE file or at https://github.com/convoo/login-fire/blob/master/LICENSE.
66
-->
77
<link rel="import" href="../polymer/polymer.html">
8-
<link rel="import" href="./login-fire-common-behavior.html">
8+
<link rel="import" href="./localize-behavior.html">
9+
<link rel="import" href="./login-fire-social-behavior.html">
910
<link rel="import" href="../iron-flex-layout/iron-flex-layout.html">
10-
<link rel="import" href="./login-fire-button.html">
11+
<link rel="import" href="./paper-social-button.html">
1112

1213
<!--
1314
A panel of buttons to authenticate a user with federated identity providers such as
@@ -25,30 +26,12 @@
2526
<login-fire-social app-name="myApp" providers="google, facebook, twitter, github, anonymous"></login-fire-social>
2627
```
2728
28-
### Localization
29-
30-
You can specify the following codes and language in a JSON file passed to the
31-
`localesFile` property to update the text used. Here are the defaults:
32-
33-
```
34-
"en": {
35-
"lf-signup-facebook": "Sign up with Facebook",
36-
"lf-signup-google": "Sign up with Google",
37-
"lf-signup-twitter": "Sign up with Twitter",
38-
"lf-signup-github": "Sign up with GitHub",
39-
"lf-signup-anonymous": "Sign up anonymously",
40-
"lf-signin-facebook": "Sign in with Facebook",
41-
"lf-signin-google": "Sign in with Google",
42-
"lf-signin-twitter": "Sign in with Twitter",
43-
"lf-signin-github": "Sign in with GitHub",
44-
"lf-signin-anonymous": "Sign in anonymously"
45-
}
46-
```
47-
4829
### Styling
4930
5031
Style the buttons with CSS as you would a normal DOM element. The following
51-
custom properties and mixins are available:
32+
custom properties and mixins are available. You can find more custom CSS
33+
properties in the "Styling" section of the `paper-social-button` element
34+
documentation.
5235
5336
Custom property | Description | Default
5437
-- | -- | --
@@ -77,55 +60,48 @@
7760
@apply --login-fire-social;
7861
}
7962

80-
login-fire-button {
63+
paper-social-button {
8164
width: 100%;
8265
margin-bottom: 10px;
8366
}
8467

85-
:host([horizontal]) login-fire-button {
68+
:host([horizontal]) paper-social-button {
8669
width: inherit;
8770
min-width: 140px;
8871
margin-bottom: 0;
8972
}
9073
</style>
9174

92-
<template is="dom-if" if="[[_showOneButton]]">
93-
<login-fire-button
94-
app-name="[[appName]]"
95-
user="{{_user}}"
96-
status-known="{{_statusKnown}}"
97-
signed-in="{{_signedIn}}"
75+
<template is="dom-if" if="[[_showOneButton]]" restamp>
76+
<paper-social-button
77+
signed-in="[[_signedIn]]"
9878
mini$="[[mini]]"
9979
flat$="[[flat]]"
100-
no-sign-in="[[noSignIn]]"
101-
no-sign-out="[[noSignOut]]"
102-
show-sign-up="{{showSignUp}}"
80+
no-sign-in
10381
locales-file="[[localesFile]]"
10482
language="[[language]]"
105-
debug="[[debug]]">
106-
</login-fire-button>
83+
in-progress="[[inProgress]]"
84+
disabled$="[[inProgress]]"
85+
on-tap="signOut">
86+
</paper-social-button>
10787
</template>
10888

109-
<template is="dom-if" if="[[!_showOneButton]]">
89+
<template is="dom-if" if="[[!_showOneButton]]" restamp>
11090
<template is="dom-repeat" items="{{_providers}}">
111-
<login-fire-button
112-
id="lfb[[item.id]]"
113-
app-name="[[appName]]"
114-
provider="[[item.id]]"
115-
scopes="[[item.scopes]]"
116-
user="{{_user}}"
117-
status-known="{{_statusKnown}}"
118-
signed-in="{{_signedIn}}"
91+
<paper-social-button
92+
provider="[[item]]"
93+
signed-in="[[_signedIn]]"
11994
mini$="[[mini]]"
12095
flat$="[[flat]]"
121-
redirect="[[redirect]]"
12296
no-sign-in="[[noSignIn]]"
12397
no-sign-out="[[noSignOut]]"
12498
show-sign-up="{{showSignUp}}"
12599
locales-file="[[localesFile]]"
126100
language="[[language]]"
127-
debug="[[debug]]">
128-
</login-fire-button>
101+
in-progress="[[inProgress]]"
102+
disabled$="[[inProgress]]"
103+
on-tap="_onClick">
104+
</paper-social-button>
129105
</template>
130106
</template>
131107

@@ -135,7 +111,10 @@
135111
Polymer({
136112
is: 'login-fire-social',
137113

138-
behaviors: [Convoo.LoginFireCommonBehavior],
114+
behaviors: [
115+
Convoo.LocalizeBehavior,
116+
Convoo.LoginFireSocialBehavior
117+
],
139118

140119
properties: {
141120

@@ -149,6 +128,16 @@
149128
value: false
150129
},
151130

131+
/**
132+
* Flat buttons, yes or no.
133+
*
134+
* @type {Boolean}
135+
*/
136+
flat: {
137+
type: Boolean,
138+
value: false
139+
},
140+
152141
/**
153142
* Providers names. A list of the providers names, seperated by comma, to
154143
* use for authentication. A button is displayed for each provider.
@@ -219,22 +208,15 @@
219208
'_scopesChanged(facebookScopes, githubScopes, googleScopes)'
220209
],
221210

222-
/**
223-
* Signs the user out. The provider used for the sign-in has no incidence.
224-
*/
225-
signOut: function() {
226-
this.$$('login-fire-button').signOut();
227-
},
228-
229211
/**
230212
* Signs the user in using the target provider.
231213
*
232214
* @param {String} provider name
233215
*/
234216
signInWith: function(provider) {
235-
var btn = this.$$('#lfb' + provider);
236-
if (btn) {
237-
btn.signIn();
217+
let prov = this._providers.find(p => p.id == provider);
218+
if (prov) {
219+
this._signInWithProvider(prov);
238220
}
239221
},
240222

@@ -277,12 +259,27 @@
277259
'github': githubScopes,
278260
'google': googleScopes
279261
};
280-
this._providers.forEach(function(provider, index) {
262+
this._providers.forEach((provider, index) => {
281263
if (provider.isSocialNetwork) {
282264
provider.scopes = scopes[provider.id];
283265
this.notifyPath('_providers.' + index + '.scopes');
284266
}
285-
}.bind(this));
267+
});
268+
},
269+
270+
_onClick: function(event) {
271+
this._signInWithProvider(event.target.provider);
272+
},
273+
274+
/**
275+
* Signs in using the given provider.
276+
*
277+
* @param {Object} provider the provider to be used to sign in
278+
*/
279+
_signInWithProvider: function(provider) {
280+
this.set('provider', provider.id);
281+
this.set('scopes', provider.scopes);
282+
this.signInOrOut();
286283
}
287284
});
288285
</script>

test/login-fire-social_test.html

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
<!doctype html>
2+
3+
<html>
4+
5+
<head>
6+
<title>login-fire-social test</title>
7+
<meta charset="utf-8">
8+
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1, user-scalable=yes">
9+
<script src="../../webcomponentsjs/webcomponents-lite.js"></script>
10+
<script src="../../web-component-tester/browser.js"></script>
11+
<link rel="import" src="../../test-fixture/test-fixture.html">
12+
13+
<link rel="import" href="../../polymerfire/firebase-app.html">
14+
<link rel="import" href="../login-fire-social.html">
15+
</head>
16+
17+
<body>
18+
19+
<firebase-app name="loginFireSocialTest" api-key="AIzaSyAhoCXxkY-ffNwA_7L7HIwBVpASYj1btNE" auth-domain="convoo-login-demo.firebaseapp.com" database-url="https://convoo-login-demo.firebaseio.com">
20+
</firebase-app>
21+
22+
<test-fixture id="Default">
23+
<template>
24+
<login-fire-social app-name="loginFireSocialTest"></login-fire-social>
25+
</template>
26+
</test-fixture>
27+
28+
<script>
29+
/**
30+
* Adds delay to a function call. Used for assertions after templates "dom-if"
31+
* and "dom-repeat" restamping. Seems those tempaltes need time for re-redering.
32+
*/
33+
const afterNextRender = (f, delay = 5) => setTimeout(f, delay);
34+
35+
describe('Behavior Audit - Fixture: Default', function() {
36+
let social;
37+
38+
beforeEach(function(done) {
39+
social = fixture('Default');
40+
afterNextRender(done);
41+
});
42+
43+
it('Should display only "Anonymous" button', function() {
44+
let buttons = (social.shadowRoot || social).querySelectorAll('paper-social-button');
45+
expect(typeof buttons).to.be.Array;
46+
expect(buttons.length).to.be.equal(1);
47+
});
48+
49+
it('Should have only "Anonymous" provider in its list', function() {
50+
expect(social.providers).to.be.equal('anonymous');
51+
expect(social._providers.length).to.be.equal(1);
52+
expect(social._providers[0].id).to.be.equal('anonymous');
53+
});
54+
55+
it('Should display buttons in same order as its provider list', function() {
56+
social.providers = 'twitter, google, facebook';
57+
expect(social._providers.length).to.be.equal(3);
58+
expect(social._providers[0].id).to.be.equal('twitter');
59+
expect(social._providers[1].id).to.be.equal('google');
60+
expect(social._providers[2].id).to.be.equal('facebook');
61+
});
62+
63+
it('Should ignore invalid providers', function() {
64+
social.providers = 'facebook, gooooogle, , twitter';
65+
expect(social._providers.length).to.be.equal(2);
66+
expect(social._providers[0].id).to.be.equal('facebook');
67+
expect(social._providers[1].id).to.be.equal('twitter');
68+
});
69+
70+
it('Should sign-in with the provider associated to the clicked button', function(done) {
71+
social.providers = 'facebook, google, twitter';
72+
afterNextRender(() => {
73+
const button = (social.shadowRoot || social).querySelectorAll('paper-social-button')[1];
74+
stub('login-fire-social', {
75+
signInOrOut: null,
76+
});
77+
button.addEventListener('click', function(event) {
78+
expect(social.provider).to.be.equal('google');
79+
expect(social.provider).to.be.equal(event.target.provider.id);
80+
done();
81+
})
82+
button.click();
83+
});
84+
});
85+
86+
it('Should display only a sign-out button when user is signed-in', function(done) {
87+
social.addEventListener('signedin', function() {
88+
afterNextRender(() => {
89+
expect(social.signedIn).to.be.true;
90+
let buttons = (social.shadowRoot || social).querySelectorAll('paper-social-button');
91+
expect(buttons.length).to.be.equal(1);
92+
expect(buttons[0]._text).to.contain('Sign out');
93+
done();
94+
});
95+
});
96+
(social.shadowRoot || social).querySelector('paper-social-button').click();
97+
});
98+
99+
it('Should apply attribute "flat" on all buttons', function() {
100+
social.flat = true;
101+
let buttons = social.root.querySelectorAll('paper-social-button');
102+
for (const button of buttons) {
103+
expect(button.flat).to.be.true;
104+
}
105+
});
106+
107+
it('Should apply attribute "mini" on all buttons', function() {
108+
social.mini = true;
109+
let buttons = social.root.querySelectorAll('paper-social-button');
110+
for (const button of buttons) {
111+
expect(button.mini).to.be.true;
112+
}
113+
});
114+
});
115+
116+
a11ySuite('Default', [], function() {
117+
social = fixture('Default');
118+
});
119+
</script>
120+
</body>
121+
122+
</html>

0 commit comments

Comments
 (0)