0

I'm having some issues with my Unit Tests for an Angular application that is intended to be an Add-In for Outlook.

The code itself runs fine without errors but the tests are routinely failing.

The errors I'm getting are the following:

ReferenceError: Office is not defined

ReferenceError: fabric is not defined

The tests fail on any method that makes use of Office.js or Fabric. So for example if a method was the following:

  public getName() {
    this.item = Office.context.mailbox.item;
    return this.item.from.displayName;
  }

It will fail with the error that office is not defined.

Both Office and Fabric are added to the application via the index.html file:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Firefish Outlook Addin</title>

  <base href="/AddinClient/">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-js/1.4.0/css/fabric.min.css" />
  <link rel="stylesheet" href="https://static2.sharepointonline.com/files/fabric/office-ui-fabric-js/1.4.0/css/fabric.components.min.css" />
  <script src="assets/js/fabric.js"></script>
  <script src="https://appsforoffice.microsoft.com/lib/1/hosted/Office.js" type="text/javascript"></script>
</head>
<body>
  <app-root></app-root>
</body>
</html>

And office in particular is initialised in the main.ts file:

import { enableProdMode } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';

import { AppModule } from './modules/app/app.module';
import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

Office.initialize = function () {
  platformBrowserDynamic()
    .bootstrapModule(AppModule)
    .catch(err => console.error(err));
};

I have been looking online for potential solutions and unfortunately can't find any. My Karma.conf.js file is the following:

module.exports = function (config) {
  config.set({
    basePath: '',
    frameworks: ['jasmine', '@angular-devkit/build-angular'],
    plugins: [
      require('karma-jasmine'),
      require('karma-chrome-launcher'),
      require('karma-jasmine-html-reporter'),
      require('karma-coverage-istanbul-reporter'),
      require('@angular-devkit/build-angular/plugins/karma')
    ],
    client: {
      clearContext: false // leave Jasmine Spec Runner output visible in browser
    },
    coverageIstanbulReporter: {
      dir: require('path').join(__dirname, '../coverage'),
      reports: ['html', 'lcovonly'],
      fixWebpackSourcePaths: true
    },
    Files: ["https://appsforoffice.microsoft.com/lib/1/hosted/Office.js"],
    reporters: ['progress', 'kjhtml'],
    port: 9876,
    colors: true,
    logLevel: config.LOG_INFO,
    autoWatch: true,
    browsers: ['Chrome'],
    singleRun: false
  });
};

and my tsconfig.spec.json file is the following:

{
  "extends": "../tsconfig.json",
  "compilerOptions": {
    "outDir": "../out-tsc/spec",
    "types": [
      "jasmine",
      "node",
      "@types/office-js"
    ]
  },

  "files": [
    "test.ts",
    "polyfills.ts"
  ],
  "include": [
    "**/*.spec.ts",
    "**/*.d.ts",
    "../node_modules/office-ui-fabric-js/src/components/Dropdown/Dropdown.ts",
    "../node_modules/office-ui-fabric-js/src/components/Button/Button.ts",
    "../node_modules/office-ui-fabric-js/src/components/TextField/TextField.ts",
    "../node_modules/office-ui-fabric-js/src/components/RadioButton/RadioButton.ts",
    "../node_modules/office-ui-fabric-js/src/components/Spinner/Spinner.ts",
    "../node_modules/office-ui-fabric-js/src/components/ProgressIndicator/ProgressIndicator.ts"
  ]
}

So I'm adding the necessary references to the files for Office and fabric.

Is this a case that I'd need to create mocks of Office and fabric?

Durga
  • 15,263
  • 2
  • 28
  • 52
Andrew Ferguson
  • 179
  • 1
  • 3
  • 15
  • You have to import the 2 types on test file – osiris85 Nov 21 '18 at 11:18
  • in the `tests.ts` file, you should add your dependencies. Also, it's a bad practice to use scripts in the head of the index, you should use the `angular.json` file to import JS scripts. –  Nov 21 '18 at 11:19

1 Answers1

3

So I found out how to resolve this issue.

For fabric since there was a local copy of this we were using I could add a reference to it in the angular.json file under the test section:

"test": {
  "builder": "@angular-devkit/build-angular:karma",
  "options": {
    "main": "src/test.ts",
    "polyfills": "src/polyfills.ts",
    "tsConfig": "src/tsconfig.spec.json",
    "karmaConfig": "src/karma.conf.js",
    "styles": [
      "src/styles.scss"
    ],
    "scripts": ["src/assets/js/fabric.js"],
    "assets": [
      "src/assets"
    ]
  }
}

For the Office issue I put the following in my spec class to get round the issue:

const officeScript = 'https://appsforoffice.microsoft.com/lib/1/hosted/Office.js';
const node = document.createElement('script');
node.src = officeScript;
node.type = 'text/javascript';
node.async = false;
node.charset = 'utf-8';
document.getElementsByTagName('head')[0].appendChild(node);
Andrew Ferguson
  • 179
  • 1
  • 3
  • 15