ng-meta
Advanced tools
Comparing version 0.3.4 to 0.3.5
{ | ||
"name": "ngMeta", | ||
"version": "0.3.3", | ||
"version": "0.3.5", | ||
"authors": [ | ||
@@ -5,0 +5,0 @@ "Vinay Gopinath <vinayg18@gmail.com>" |
{ | ||
"name": "ng-meta", | ||
"version": "0.3.4", | ||
"version": "0.3.5", | ||
"description": "Meta tags support for AngularJS single page applications (SPA)", | ||
@@ -47,5 +47,5 @@ "main": "src/ngMeta.js", | ||
"karma-mocha-reporter": "^1.1.1", | ||
"karma-phantomjs-launcher": "^0.2.1", | ||
"karma-phantomjs2-launcher": "^0.5.0", | ||
"phantomjs": "^1.9.18" | ||
} | ||
} |
278
README.md
@@ -6,27 +6,15 @@ # ngMeta | ||
* [Demo](#demo) | ||
* [Introduction](#introduction) | ||
* [Install](#install) | ||
* [Getting Started](#getting-started) | ||
* [Meta tags](#meta-tags) | ||
* [Options](#options) | ||
* [General options](#general-options) | ||
* [Defaults](#defaults) | ||
* [Setting meta tags dynamically](#setting-meta-tags-dynamically) | ||
* [Dynamic meta tags](#dynamic-meta-tags) | ||
* [Support For Other Crawlers](#support-for-other-crawlers) | ||
* [Debugging](#debugging) | ||
* [Websites using ngMeta](#websites-using-ngmeta) | ||
* [Further reading](#further-reading) | ||
* [Licence](#mit-licence) | ||
## Demo | ||
Visit [vinaygopinath.github.io/ngMeta](http://vinaygopinath.github.io/ngMeta) | ||
[vinaygopinath.github.io/ngMeta](http://vinaygopinath.github.io/ngMeta) | ||
## Introduction | ||
Google [announced in 2014](http://googlewebmastercentral.blogspot.com/2014/05/understanding-web-pages-better.html) that sites using Javascript are rendered the way users see it, and indeed, Webmaster Tool's [Fetch as Google](https://www.google.com/webmasters/tools/googlebot-fetch) can confirm that. | ||
However, articles on SEO in AngularJS single page applications (SPA) continue to recommend the use of the `escaped_fragment` technique and redirection of crawler bot requests to prerendering services. | ||
Pascal Floride's article, [AngularJS & SEO](https://weluse.de/blog/angularjs-seo-finally-a-piece-of-cake.html) describes a simple Angular service-based technique to dynamically update the meta tags of a site based on the route. | ||
Built on this idea, ngMeta lets Angular SPAs set common tags like title and description as well as [Open Graph](http://ogp.me/) tags, both on ui-router and ngRoute. | ||
## Install | ||
@@ -48,167 +36,120 @@ | ||
Add it as a dependency of your module. | ||
1. Add `ngMeta` as a dependency of your module. ngMeta supports ui-router and ngRoute. | ||
```js | ||
angular.module('YourApp',['ngMeta']); | ||
``` | ||
```js | ||
angular.module('YourApp',['ngMeta']); | ||
``` | ||
2. Add `meta` objects to your routes (ngRoute) or states (ui-router) and specify the meta tags appropriate to each view. Other than `title` and `titleSuffix`, which are reserved properties that affect the title of the page, the tag properties can be named as per your choice. | ||
```js | ||
.config(function ($routeProvider, ngMetaProvider) { | ||
$routeProvider | ||
.when('/home', { | ||
templateUrl: 'home-template.html', | ||
meta: { | ||
'title': 'Home page', | ||
'description': 'This is the description shown in Google search results' | ||
} | ||
}) | ||
.when('/login', { | ||
templateUrl: 'login-template.html', | ||
meta: { | ||
'title': 'Login page', | ||
'titleSuffix': ' | Login to YourSiteName', | ||
'description': 'Login to the site' | ||
} | ||
}); | ||
... | ||
}); | ||
``` | ||
ngMeta supports ui-router and ngRoute. Add `meta` objects to your routes (ngRoute) or states (ui-router) and specify the meta tags appropriate to each view. | ||
3. **[Optional]** Set the default values of meta tags during Angular's configuration phase. If the `meta` object of a route does not contain a specific tag, the default value is used instead. | ||
```javascript | ||
//Add a suffix to all page titles | ||
ngMetaProvider.useTitleSuffix(true); | ||
```js | ||
.config(function ($routeProvider, ngMetaProvider) { | ||
// On /home, the title would change to | ||
// 'Home Page | Best Website on the Internet!' | ||
ngMetaProvider.setDefaultTitleSuffix(' | Best Website on the Internet!'); | ||
$routeProvider | ||
.when('/home', { | ||
templateUrl: 'home-template.html', | ||
meta: { | ||
//Sets 'Home Page' as the title when /home is open | ||
'title': 'Home page', | ||
'description': 'This is the description shown in Google search results' | ||
} | ||
}) | ||
.when('/login', { | ||
templateUrl: 'login-template.html', | ||
meta: { | ||
'title': 'Login page', | ||
'description': 'Login to the site' | ||
} | ||
}); | ||
... | ||
}); | ||
``` | ||
//Set defaults for arbitrary tags | ||
// Default author name | ||
ngMetaProvider.setDefaultTag('author', 'John Smith'); | ||
``` | ||
Set the default values of meta tags or change ngMeta options during Angular's configuration phase. | ||
```js | ||
//Add a suffix to all page titles | ||
ngMetaProvider.useTitleSuffix(true); | ||
4. Let `ngMeta` initialize by calling the `init()` function in the app.js `run` block | ||
```js | ||
angular.module('YourApp', ['ngRoute', 'ngMeta']) | ||
.config(function($routeProvider, ngMetaProvider) { | ||
.... | ||
}) | ||
.run(['ngMeta', function(ngMeta) { | ||
ngMeta.init(); | ||
}]); | ||
``` | ||
// On /home, the title would change to | ||
// 'Home Page | Best Website on the Internet!' | ||
ngMetaProvider.setDefaultTitleSuffix(' | Best Website on the Internet!'); | ||
5. Set the meta tags in your HTML file | ||
```html | ||
<title ng-bind="ngMeta.title"></title> | ||
<!-- OR <title>{{ngMeta.title}}</title> --> | ||
//Set defaults for arbitrary tags | ||
// Default author name | ||
ngMetaProvider.setDefaultTag('author', 'John Smith'); | ||
``` | ||
<!-- Arbitrary tags --> | ||
<meta property="og:type" content="{{ngMeta['og:type']}}" /> | ||
<meta property="og:locale" content="{{ngMeta['og:locale']}}" /> | ||
<meta name="author" content="{{ngMeta['author']}}" /> | ||
<!-- OR <meta name="author" content="{{ngMeta.author}}" /> --> | ||
<meta name="description" content="{{ngMeta.description}}" /> | ||
``` | ||
Let `ngMeta` initialize by calling the `init()` function in the app.js `run` block | ||
```js | ||
angular.module('YourApp', ['ngRoute', 'ngMeta']) | ||
.config(function($routeProvider, ngMetaProvider) { | ||
.... | ||
}) | ||
.run(function(ngMeta) { | ||
ngMeta.init(); | ||
}); | ||
``` | ||
## Defaults | ||
Don't forget to set the meta tags in index.html | ||
```html | ||
<title ng-bind="ngMeta.title"></title> | ||
<!-- OR <title>{{ngMeta.title}}</title> --> | ||
Change app-wide behaviour and set default values to tags using these methods of `ngMetaProvider`. These defaults can be overridden by defining equivalent properties in the route/state `meta` object | ||
<!-- Arbitrary tags --> | ||
<meta property="og:type" content="{{ngMeta['og:type']}}" /> | ||
<meta property="og:locale" content="{{ngMeta['og:locale']}}" /> | ||
<meta name="author" content="{{ngMeta['author']}}" /> | ||
<!-- OR <meta name="author" content="{{ngMeta.author}}" /> --> | ||
<meta name="description" content="{{ngMeta.description}}" /> | ||
``` | ||
## Meta tags | ||
Add a `meta` object within a route/state in the $routeProvider/$stateProvider. This meta object can contain arbitrary properties. | ||
```javascript | ||
.when('/login', { | ||
templateUrl: 'login-template.html', | ||
meta: { | ||
//Sets 'Login Page' as the title when /login is open | ||
//Overrides the default title (if it is defined) | ||
title: 'Login page', | ||
//The title suffix for this route. Used only when useTitleSuffix is enabled. Overrides the default titleSuffix (if it is defined) | ||
titleSuffix: 'Funny Cat Pictures', | ||
//The description of this page | ||
description: 'Login to this wonderful website!', | ||
// og:image URL | ||
'og:image': 'http://example.com/abc.jpg', | ||
//Author tag | ||
'author': 'Placeholder Name' | ||
} | ||
} | ||
``` | ||
angular.module('YourApp', [....,'ngMeta']) | ||
.config(function(ngMetaProvider) { | ||
If a route is missing any of these properties, `ngMeta` checks if a default has been defined for the missing property. If available, the default value is served. | ||
## Options | ||
Change ngMeta options using these functions of `ngMetaProvider` | ||
### General options | ||
#### Title Suffix | ||
Default: `false` | ||
Example: | ||
```javascript | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.setDefaultTitle('Fallback Title'); | ||
ngMetaProvider.setDefaultTitleSuffix(' | YourSite'); | ||
ngMetaProvider.setDefaultTag('author', 'John Smith'); | ||
}); | ||
``` | ||
Toggle the use of a title suffix. Setting it to true enables the use of an optional title suffix for all pages | ||
| Method | Default | Example | | ||
| ------ | ------- | ------- | | ||
| **useTitleSuffix(boolean)**<br/>Toggles the use of a title suffix. When enabled, the title suffix of the route (if available) or the default title suffix is appended to the title of all pages. | `false` | ngMetaProvider.useTitleSuffix(true);<br/> | | ||
| **setDefaultTitle(String)**<br/>Sets the default title for all routes. This serves as a fallback for routes that don't have a `title` property. Use this to customize titles for a few specific routes, letting other routes use the default title. | `undefined` | ngMetaProvider.setDefaultTitle('Spotify');<br/>ngMetaProvider.setDefaultTitle('Generic Title'); | | ||
| **setDefaultTitleSuffix(String)**<br/>Sets the default title suffix for all routes. This serves as a fallback for routes that don't have a `titleSuffix` property. The default title suffix is relevant only when `useTitleSuffix` is set to true. | `undefined` | ngMetaProvider.setDefaultTitleSuffix(' - Site Name');<br/>ngMetaProvider.setDefaultTitleSuffix(' - YourSite'); | | ||
| **setDefaultTag(String, String)**<br/>Sets the default value of any arbitrary tag. This serves as a fallback for routes that don't have a particular tag. | N/A | ngMetaProvider.setDefaultTag('author', 'John Smith');<br/>ngMetaProvider.setDefaultTag('ogImgUrl', 'http://example.com/img.png'); | | ||
## Defaults | ||
## Dynamic meta tags | ||
Set app-wide defaults for meta tags during Angular's configuration phase. These defaults can be overridden by defining equivalent properties in the route/state `meta` object | ||
To change meta tags dynamically (when an item in a list is clicked, for example), inject the `ngMeta` service into your controller and use one of the following methods: | ||
#### Title | ||
Example: | ||
```javascript | ||
ngMetaProvider.setDefaultTitle('Playlist') | ||
```js | ||
angular.module('YourApp') | ||
.controller(function(ngMeta) { | ||
//These examples assume useTitleSuffix is enabled, | ||
//and default titleSuffix is set to 'Playlist' | ||
//Custom title and titleSuffix | ||
ngMeta.setTitle('Eluvium', ' | Spotify'); //Title = Eluvium | Spotify | ||
//default titleSuffix | ||
ngMeta.setTitle('Eluvium'); //Title = Eluvium | Playlist | ||
//Clear the default titleSuffix | ||
ngMeta.setTitle('Eluvium',''); //Title = Eluvium | ||
ngMeta.setTag('author', 'Matthew Cooper'); | ||
ngMeta.setTag('image', 'http://placeholder.com/abc.jpg'); | ||
}); | ||
``` | ||
The default title is used when the title of a page is not specified. | ||
#### Title suffix | ||
Example: | ||
```javascript | ||
ngMetaProvider.setDefaultTitleSuffix('Free unlimited ad-free radio') | ||
``` | ||
The default title suffix is used when `useTitleSuffix` option is enabled and the title suffix of a page is not specified. | ||
#### Other tag defaults | ||
Example: | ||
```javascript | ||
ngMetaProvider.setDefaultTag('description', 'Default description text'); | ||
ngMetaProvider.setDefaultTag('og:url', 'http://example.com'); | ||
ngMetaProvider.setDefaultTag('author', 'John Smith'); | ||
``` | ||
## Setting meta tags dynamically | ||
To change meta tags dynamically (on a certain action or event), inject the `ngMeta` service into your controller and use one of the following functions: | ||
Note: Please use `setTitle` to modify the title and/or titleSuffix and `setTag` for all other tags. | ||
```js | ||
//uses default title suffix, if useTitleSuffix enabled | ||
ngMeta.setTitle('Page title'); | ||
| Method | Description | Example | | ||
| ------ | ------- | ------- | | ||
| **setTitle(String title, String titleSuffix)** | Sets the current title based on the given params. When `useTitleSuffix` is enabled and titleSuffix is not provided, it uses the default titleSuffix. | ngMeta.setTitle('Title', ' - TitleSuffix')<br/><br/>ngMeta.setTitle('Title with default titleSuffix')<br/><br/>ngMeta.setTitle('Title with no titleSuffix','') | | ||
| **setTag(String tagName, String value)** | Sets the value of an arbitrary tag, using the default value of the tag when the second param is missing. The value is accessible as {{ngMeta.tagName}} from HTML. Calling setTag with `title` or `titleSuffix` as `tagName` results in an error. Title must be modified using `setTitle` instead.|ngMeta.setTag('author', 'John Smith')<br/><br/>ngMeta.setTag('ogImage', 'http://url.com/image.png')| | ||
//results in the title 'Page Title | Example Suffix' | ||
ngMeta.setTitle('Page title', ' | Example Suffix'); | ||
//changes the description | ||
ngMeta.setTag('description', 'Song A by SingerXYZ from the 2009 album ABC'); | ||
//changes the open graph image | ||
ngMeta.setTag('og:image', 'http://example.com/large_image.png'); | ||
``` | ||
## Support For Other Crawlers | ||
@@ -222,11 +163,24 @@ | ||
You can use Facebook's [Open Graph Object Debugger](https://developers.facebook.com/tools/debug/og/object/) to see detailed information about your site's meta tags as well as a preview of the snippet shown when your site is shared. | ||
**TL;DR: ngMeta helps the Google crawler render your Angular site and read the meta tags. For other sites like Facebook/Twitter that can't render Javascript, you need to use pre-renderers or server redirects.** | ||
## Debugging | ||
To check out the tags set by ngMeta when a state/route is open, you can use the [ng-inspector Chrome extension](https://chrome.google.com/webstore/detail/ng-inspector-for-angularj/aadgmnobpdmgmigaicncghmmoeflnamj) | ||
* [ng-inspector Chrome extension](https://chrome.google.com/webstore/detail/ng-inspector-for-angularj/aadgmnobpdmgmigaicncghmmoeflnamj) shows the tags set by ngMeta when a state/route is open | ||
![ng-inspector running on an Angular SPA with ngMeta](http://i.imgur.com/3ltyKC4.png) | ||
* Facebook's [Open Graph Object Debugger](https://developers.facebook.com/tools/debug/og/object/) shows detailed information about your site's meta tags as well as a preview of the snippet shown when your site is shared. | ||
## Websites using ngMeta | ||
* [acloud.guru](https://acloud.guru) - AWS certification online learning platform | ||
To list your website here, please make a PR and add your URL in this section of README.md in this format | ||
``` | ||
"Site URL - Short description" | ||
``` | ||
## Further reading | ||
* [AngularJS & SEO - finally a piece of cake](https://weluse.de/blog/angularjs-seo-finally-a-piece-of-cake.html) | ||
* [Fetch as Google - Google Webmaster Tools](https://www.google.com/webmasters/tools/googlebot-fetch) | ||
* [Deprecating our AJAX crawling scheme - Google Webmaster Blog](https://webmasters.googleblog.com/2015/10/deprecating-our-ajax-crawling-scheme.html) | ||
* [Open Graph protocol](http://ogp.me/) | ||
## MIT Licence | ||
*Vinay Gopinath* |
@@ -81,2 +81,5 @@ (function(root, factory) { | ||
} | ||
if (tag === 'title' || tag === 'titleSuffix') { | ||
throw new Error('Attempt to set \'' + tag + '\' through \'setTag\': \'title\' and \'titleSuffix\' are reserved tag names. Please use \'ngMeta.setTitle\' instead'); | ||
} | ||
$rootScope.ngMeta[tag] = angular.isDefined(value) ? value : defaults[tag]; | ||
@@ -83,0 +86,0 @@ }; |
@@ -1,24 +0,24 @@ | ||
module.exports = function (config) { | ||
config.set({ | ||
autoWatch: false, | ||
frameworks: ['jasmine'], | ||
// basePath: '../', | ||
reporters: ['mocha'], | ||
files: [ | ||
'../bower_components/angular/angular.js', | ||
'../bower_components/angular-mocks/angular-mocks.js', | ||
'../src/**/*.js', | ||
'../test/**/*.js' | ||
], | ||
browsers: [ | ||
'PhantomJS' | ||
], | ||
plugins: [ | ||
'karma-phantomjs-launcher', | ||
'karma-jasmine', | ||
'karma-mocha-reporter' | ||
], | ||
colors: true, | ||
singleRun: true | ||
}); | ||
module.exports = function(config) { | ||
config.set({ | ||
autoWatch: false, | ||
frameworks: ['jasmine'], | ||
// basePath: '../', | ||
reporters: ['mocha'], | ||
files: [ | ||
'../bower_components/angular/angular.js', | ||
'../bower_components/angular-mocks/angular-mocks.js', | ||
'../src/**/*.js', | ||
'../test/**/*.js' | ||
], | ||
browsers: [ | ||
'PhantomJS2' | ||
], | ||
plugins: [ | ||
'karma-phantomjs2-launcher', | ||
'karma-jasmine', | ||
'karma-mocha-reporter' | ||
], | ||
colors: true, | ||
singleRun: true | ||
}); | ||
}; |
@@ -1,289 +0,237 @@ | ||
describe('Service: ngMeta', function () { | ||
var SOME_TITLE = 'Hello'; | ||
var SOME_TITLE_SUFFIX = ' | World'; | ||
var SOME_DEFAULT_TITLE = 'Title'; | ||
var SOME_DEFAULT_TITLE_SUFFIX = ' | Suffix'; | ||
'use strict'; | ||
// instantiate service | ||
var ngMeta, $rootScope, | ||
init = function () { | ||
inject(function (_ngMeta_, _$rootScope_) { | ||
ngMeta = _ngMeta_; | ||
$rootScope = _$rootScope_; | ||
}); | ||
}; | ||
var SOME_TAG = 'image'; | ||
var SOME_TAG_VALUE = 'http://example.com/image.png'; | ||
var SOME_TAG_DEFAULT_VALUE = 'http://placeholder.com/picture.jpg'; | ||
var defaultVarName = 'ngMeta'; | ||
var defaultOgType = 'website'; | ||
var defaultOgSiteName = ''; | ||
var defaultOgLocale = 'en_US'; | ||
var someDefaultTitle = 'Title'; | ||
var someDefaultTitleSuffix = ' | Suffix'; | ||
// load the service's module | ||
beforeEach(module('ngMeta')); | ||
describe('Provider: ngMetaProvider', function() { | ||
it('should create a service', function () { | ||
init(); | ||
describe('Basic checks', function() { | ||
expect(!!ngMeta).toBe(true); | ||
it('should provide the setDefaultTitle function', function() { | ||
module(function(ngMetaProvider) { | ||
expect(ngMetaProvider.setDefaultTitle).toBeDefined(); | ||
}); | ||
}); | ||
describe('App-wide one-time configuration', function () { | ||
it('should provide the setDefaultTitleSuffix function', function() { | ||
module(function(ngMetaProvider) { | ||
expect(ngMetaProvider.setDefaultTitleSuffix).toBeDefined(); | ||
}); | ||
}); | ||
describe('Variable name', function () { | ||
it('should provide the setDefaultTag function', function() { | ||
module(function(ngMetaProvider) { | ||
expect(ngMetaProvider.setDefaultTag).toBeDefined(); | ||
}); | ||
}); | ||
}); | ||
}); | ||
it('should default to the ngMeta variable name', function () { | ||
describe('Service: ngMeta', function() { | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
'use strict'; | ||
expect($rootScope[defaultVarName]).toBeDefined(); | ||
}); | ||
var ngMeta, $rootScope; | ||
it('should support changing the variable name', function () { | ||
// instantiate service | ||
var injectDependencies = function() { | ||
inject(function(_ngMeta_, _$rootScope_) { | ||
ngMeta = _ngMeta_; | ||
$rootScope = _$rootScope_; | ||
}); | ||
}; | ||
var someNewVarName = 'MetaTag'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setName(someNewVarName); | ||
}); | ||
// load the service's module | ||
beforeEach(module('ngMeta')); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
describe('Init: init()', function() { | ||
expect($rootScope[someNewVarName]).toBeDefined(); | ||
}); | ||
}); | ||
//Inject dependencies | ||
beforeEach(function() { | ||
injectDependencies(); | ||
}); | ||
describe('Title suffix', function () { | ||
it('should provide an init function', function() { | ||
expect(ngMeta.init).toBeDefined(); | ||
}); | ||
it('should default to false on title suffix use', function () { | ||
//angular-route support | ||
it('should set up a broadcast listener for $routeChangeSuccess', function() { | ||
spyOn($rootScope, '$on'); | ||
ngMeta.init(); | ||
expect($rootScope.$on).toHaveBeenCalledWith('$routeChangeSuccess', jasmine.any(Function)); | ||
}); | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(false); | ||
ngMetaProvider.setDefaultTitle(someDefaultTitle); | ||
ngMetaProvider.setDefaultTitleSuffix(someDefaultTitleSuffix); | ||
}); | ||
//ui-router support | ||
it('should set up a broadcast listener for $stateChangeSuccess', function() { | ||
spyOn($rootScope, '$on'); | ||
ngMeta.init(); | ||
expect($rootScope.$on).toHaveBeenCalledWith('$stateChangeSuccess', jasmine.any(Function)); | ||
}); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
describe('Title: setTitle()', function() { | ||
expect($rootScope[defaultVarName].title).toEqual(someDefaultTitle); | ||
}); | ||
describe('Basic checks', function() { | ||
it('should use the title suffix when it is enabled', function () { | ||
//Inject dependencies | ||
beforeEach(function() { | ||
injectDependencies(); | ||
}); | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.setDefaultTitle(someDefaultTitle); | ||
ngMetaProvider.setDefaultTitleSuffix(someDefaultTitleSuffix); | ||
}); | ||
it('should provide the setTitle() function', function() { | ||
expect(ngMeta.setTitle).toBeDefined(); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
it('should throw an error when init has not been called', function() { | ||
expect(ngMeta.setTitle).toThrow(); | ||
}); | ||
}); | ||
expect($rootScope[defaultVarName].title).toEqual(someDefaultTitle + someDefaultTitleSuffix); | ||
}); | ||
}); | ||
describe('Default Functionality', function() { | ||
describe('OpenGraph type', function () { | ||
beforeEach(function() { | ||
injectDependencies(); | ||
ngMeta.init(); | ||
}); | ||
it('should default to website for og:type', function () { | ||
it('should update the title', function() { | ||
ngMeta.setTitle(SOME_TITLE); | ||
expect($rootScope.ngMeta.title).toBe(SOME_TITLE); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
it('should ignore the titleSuffix param by default', function() { | ||
ngMeta.setTitle(SOME_TITLE, SOME_TITLE_SUFFIX); | ||
expect($rootScope.ngMeta.title).toBe(SOME_TITLE); | ||
}); | ||
}); | ||
expect($rootScope[defaultVarName].ogType).toEqual(defaultOgType); | ||
}); | ||
describe('Customized Functionality', function() { | ||
it('should support setting the og:type', function () { | ||
var someOgType = 'article'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setOgType(someOgType); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogType).toEqual(someOgType); | ||
}); | ||
it('should use the titleSuffix param when useTitleSuffix config is enabled', function() { | ||
module(function(ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(true); | ||
}); | ||
injectDependencies(); | ||
ngMeta.init(); | ||
describe('OpenGraph site name', function () { | ||
ngMeta.setTitle(SOME_TITLE, SOME_TITLE_SUFFIX); | ||
it('should default to empty string for og:site_name', function () { | ||
expect($rootScope.ngMeta.title).toBe(SOME_TITLE + SOME_TITLE_SUFFIX); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogSiteName).toEqual(defaultOgSiteName); | ||
}); | ||
it('should support setting the og:site_name', function () { | ||
var someOgSiteName = 'GitHub'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setOgSiteName(someOgSiteName); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogSiteName).toEqual(someOgSiteName); | ||
}); | ||
it('should use the default titleSuffix param when useTitleSuffix is enabled and no titleSuffix argument is provided', function() { | ||
module(function(ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.setDefaultTitleSuffix(SOME_DEFAULT_TITLE_SUFFIX); | ||
}); | ||
injectDependencies(); | ||
ngMeta.init(); | ||
describe('OpenGraph locale', function () { | ||
ngMeta.setTitle(SOME_TITLE); | ||
it('should default to en_US for og:locale', function () { | ||
expect($rootScope.ngMeta.title).toBe(SOME_TITLE + SOME_DEFAULT_TITLE_SUFFIX); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogLocale).toEqual(defaultOgLocale); | ||
}); | ||
it('should support setting the og:locale', function () { | ||
var someOgLocale = 'en_IN'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setOgLocale(someOgLocale); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogLocale).toEqual(someOgLocale); | ||
}); | ||
it('should override the default titleSuffix param when useTitleSuffix is enabled and a titleSuffix argument is provided', function() { | ||
module(function(ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.setDefaultTitleSuffix(SOME_DEFAULT_TITLE_SUFFIX); | ||
}); | ||
injectDependencies(); | ||
ngMeta.init(); | ||
}); | ||
ngMeta.setTitle(SOME_TITLE, SOME_TITLE_SUFFIX); | ||
describe('Defaults configuration', function () { | ||
expect($rootScope.ngMeta.title).toBe(SOME_TITLE + SOME_TITLE_SUFFIX); | ||
}); | ||
it('should support setting a default title', function () { | ||
var someDefaultTitle = 'Lorem Ipsum'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setDefaultTitle(someDefaultTitle); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope.ngMeta.title).toEqual(someDefaultTitle); | ||
it('should use the default title [and default titleSuffix] when no arguments are provided', function() { | ||
module(function(ngMetaProvider) { | ||
ngMetaProvider.useTitleSuffix(true); | ||
ngMetaProvider.setDefaultTitle(SOME_DEFAULT_TITLE); | ||
ngMetaProvider.setDefaultTitleSuffix(SOME_DEFAULT_TITLE_SUFFIX); | ||
}); | ||
injectDependencies(); | ||
ngMeta.init(); | ||
it('should support setting a default title suffix', function () { | ||
ngMeta.setTitle(); | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setDefaultTitle(someDefaultTitle); | ||
ngMetaProvider.setDefaultTitleSuffix(someDefaultTitleSuffix); | ||
ngMetaProvider.useTitleSuffix(true); | ||
}); | ||
expect($rootScope.ngMeta.title).toBe(SOME_DEFAULT_TITLE + SOME_DEFAULT_TITLE_SUFFIX); | ||
}); | ||
}); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
describe('Tag: setTag()', function() { | ||
expect($rootScope.ngMeta.title).toEqual(someDefaultTitle + someDefaultTitleSuffix); | ||
}); | ||
describe('Basic checks', function() { | ||
//Inject dependencies | ||
beforeEach(function() { | ||
injectDependencies(); | ||
}); | ||
it('should support setting a default description', function () { | ||
it('should provide the setTag() function', function() { | ||
expect(ngMeta.setTag).toBeDefined(); | ||
}); | ||
var someDescription = 'This is a description'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setDefaultDescription(someDescription); | ||
}); | ||
it('should throw an error when init has not been called', function() { | ||
expect(ngMeta.setTag).toThrow(); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
it('should throw an error when the tag name is title', function() { | ||
ngMeta.init(); | ||
expect(function() { | ||
ngMeta.setTag('title', SOME_TAG_VALUE); | ||
}).toThrow(); | ||
}); | ||
expect($rootScope[defaultVarName].description).toEqual(someDescription); | ||
}); | ||
it('should throw an error when the tag name is titleSuffix', function() { | ||
ngMeta.init(); | ||
expect(function() { | ||
ngMeta.setTag('titleSuffix', SOME_TAG_VALUE); | ||
}).toThrow(); | ||
}); | ||
}); | ||
it('should support setting a default og:image', function () { | ||
describe('Default Functionality', function() { | ||
var someOgImgUrl = 'http://example.com/abc.jpg'; | ||
module(function (ngMetaProvider) { | ||
ngMetaProvider.setDefaultOgImgUrl(someOgImgUrl); | ||
}); | ||
beforeEach(function() { | ||
injectDependencies(); | ||
ngMeta.init(); | ||
}); | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', {}); | ||
expect($rootScope[defaultVarName].ogImgUrl).toEqual(someOgImgUrl); | ||
}); | ||
it('should set the tag to the given value', function() { | ||
ngMeta.setTag(SOME_TAG, SOME_TAG_VALUE); | ||
expect($rootScope.ngMeta[SOME_TAG]).toBe(SOME_TAG_VALUE); | ||
}); | ||
}); | ||
describe('Runtime functions', function () { | ||
describe('Customized Functionality', function() { | ||
it('should support setting a title dynamically', function () { | ||
var someTitle = 'ABCD'; | ||
ngMeta.setTitle(someTitle); | ||
expect($rootScope[defaultVarName].title).toEqual(someTitle); | ||
beforeEach(function() { | ||
module(function(ngMetaProvider) { | ||
ngMetaProvider.setDefaultTag(SOME_TAG, SOME_TAG_DEFAULT_VALUE); | ||
}); | ||
injectDependencies(); | ||
ngMeta.init(); | ||
}); | ||
it('should support setting a description dynamically', function () { | ||
it('should use the default tag value when the tag value is not available', function() { | ||
ngMeta.setTag(SOME_TAG); | ||
expect($rootScope.ngMeta[SOME_TAG]).toBe(SOME_TAG_DEFAULT_VALUE); | ||
}); | ||
var someDescription = 'Some description here'; | ||
ngMeta.setDescription(someDescription); | ||
expect($rootScope[defaultVarName].description).toEqual(someDescription); | ||
}); | ||
it('should support setting an og:image dynamically', function () { | ||
var someOgImgUrl = 'http://example.com/123.jpg'; | ||
ngMeta.setOgImgUrl(someOgImgUrl); | ||
expect($rootScope[defaultVarName].ogImgUrl).toEqual(someOgImgUrl); | ||
}); | ||
it('should override the default tag value when the tag value is available', function() { | ||
ngMeta.setTag(SOME_TAG, SOME_TAG_VALUE); | ||
expect($rootScope.ngMeta[SOME_TAG]).toBe(SOME_TAG_VALUE); | ||
}); | ||
}); | ||
}); | ||
describe('Route navigation meta changes', function () { | ||
it('should update meta tags with new meta object when the route changes', function () { | ||
var firstRouteMeta = { | ||
title: 'First title', | ||
description: 'First description' | ||
}; | ||
var secondRouteMeta = { | ||
title: 'Second title', | ||
description: 'Second description' | ||
}; | ||
var firstRouteMock = { | ||
meta: firstRouteMeta | ||
}; | ||
var secondRouteMock = { | ||
meta: secondRouteMeta | ||
}; | ||
init(); | ||
//Simulate route change | ||
$rootScope.$broadcast('$routeChangeSuccess', firstRouteMock); | ||
$rootScope.$broadcast('$routeChangeSuccess', secondRouteMock); | ||
expect($rootScope[defaultVarName].title).toEqual(secondRouteMeta.title); | ||
expect($rootScope[defaultVarName].description).toEqual(secondRouteMeta.description); | ||
}); | ||
}); | ||
}); |
13
33787
617
183