From ab1e70016dde3ef93498bca99d0aa8b38e6d7f38 Mon Sep 17 00:00:00 2001 From: Stefan Giehl Date: Tue, 11 Feb 2020 09:05:27 +0100 Subject: Renames CustomPiwikJs plugin to CustomJsTracker (#15505) * Renames CustomPiwikJs plugin to CustomTrackerJs * adds bc for old api class name * adds update to rename plugin in exisiting config * update ui tests * rename again * remove old events * improve changelog * remove bc fallback * Improve migration * use tagmanager submodule * updates UI files --- plugins/CustomJsTracker/.gitignore | 2 + plugins/CustomJsTracker/API.php | 42 ++++ plugins/CustomJsTracker/Commands/UpdateTracker.php | 66 ++++++ plugins/CustomJsTracker/CustomJsTracker.php | 41 ++++ .../CustomJsTracker/Diagnostic/TrackerJsCheck.php | 82 +++++++ .../Exception/AccessDeniedException.php | 15 ++ plugins/CustomJsTracker/File.php | 100 +++++++++ plugins/CustomJsTracker/Tasks.php | 25 +++ plugins/CustomJsTracker/TrackerUpdater.php | 165 ++++++++++++++ .../TrackingCode/JsTestPluginTrackerFiles.php | 27 +++ .../TrackingCode/PiwikJsManipulator.php | 77 +++++++ .../TrackingCode/PluginTrackerFiles.php | 110 +++++++++ plugins/CustomJsTracker/config/config.php | 7 + plugins/CustomJsTracker/config/tracker.php | 2 + plugins/CustomJsTracker/lang/cs.json | 5 + plugins/CustomJsTracker/lang/da.json | 6 + plugins/CustomJsTracker/lang/de.json | 8 + plugins/CustomJsTracker/lang/el.json | 8 + plugins/CustomJsTracker/lang/en.json | 8 + plugins/CustomJsTracker/lang/eo.json | 7 + plugins/CustomJsTracker/lang/es-ar.json | 8 + plugins/CustomJsTracker/lang/es.json | 8 + plugins/CustomJsTracker/lang/fi.json | 7 + plugins/CustomJsTracker/lang/fr.json | 8 + plugins/CustomJsTracker/lang/id.json | 5 + plugins/CustomJsTracker/lang/it.json | 8 + plugins/CustomJsTracker/lang/ja.json | 8 + plugins/CustomJsTracker/lang/nb.json | 6 + plugins/CustomJsTracker/lang/nl.json | 6 + plugins/CustomJsTracker/lang/pl.json | 6 + plugins/CustomJsTracker/lang/pt-br.json | 8 + plugins/CustomJsTracker/lang/pt.json | 8 + plugins/CustomJsTracker/lang/ru.json | 8 + plugins/CustomJsTracker/lang/sq.json | 8 + plugins/CustomJsTracker/lang/sr.json | 7 + plugins/CustomJsTracker/lang/sv.json | 8 + plugins/CustomJsTracker/lang/tr.json | 8 + plugins/CustomJsTracker/lang/uk.json | 8 + plugins/CustomJsTracker/lang/zh-cn.json | 8 + plugins/CustomJsTracker/lang/zh-tw.json | 8 + .../Framework/Mock/PluginTrackerFilesMock.php | 36 +++ .../CustomJsTracker/tests/Integration/ApiTest.php | 84 +++++++ .../CustomJsTracker/tests/Integration/FileTest.php | 210 ++++++++++++++++++ .../tests/Integration/PiwikJsManipulatorTest.php | 73 ++++++ .../tests/Integration/PluginTrackerFilesTest.php | 143 ++++++++++++ .../tests/Integration/TrackerUpdaterTest.php | 246 +++++++++++++++++++++ .../tests/System/PiwikJsContentTest.php | 39 ++++ .../tests/resources/MyTestTarget2.js | 16 ++ plugins/CustomJsTracker/tests/resources/test.js | 2 + .../CustomJsTracker/tests/resources/testpiwik.js | 6 + plugins/CustomJsTracker/tests/resources/tracker.js | 4 + .../CustomJsTracker/tests/resources/tracker.min.js | 2 + 52 files changed, 1813 insertions(+) create mode 100644 plugins/CustomJsTracker/.gitignore create mode 100644 plugins/CustomJsTracker/API.php create mode 100644 plugins/CustomJsTracker/Commands/UpdateTracker.php create mode 100644 plugins/CustomJsTracker/CustomJsTracker.php create mode 100644 plugins/CustomJsTracker/Diagnostic/TrackerJsCheck.php create mode 100644 plugins/CustomJsTracker/Exception/AccessDeniedException.php create mode 100644 plugins/CustomJsTracker/File.php create mode 100644 plugins/CustomJsTracker/Tasks.php create mode 100644 plugins/CustomJsTracker/TrackerUpdater.php create mode 100644 plugins/CustomJsTracker/TrackingCode/JsTestPluginTrackerFiles.php create mode 100644 plugins/CustomJsTracker/TrackingCode/PiwikJsManipulator.php create mode 100644 plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php create mode 100644 plugins/CustomJsTracker/config/config.php create mode 100644 plugins/CustomJsTracker/config/tracker.php create mode 100644 plugins/CustomJsTracker/lang/cs.json create mode 100644 plugins/CustomJsTracker/lang/da.json create mode 100644 plugins/CustomJsTracker/lang/de.json create mode 100644 plugins/CustomJsTracker/lang/el.json create mode 100644 plugins/CustomJsTracker/lang/en.json create mode 100644 plugins/CustomJsTracker/lang/eo.json create mode 100644 plugins/CustomJsTracker/lang/es-ar.json create mode 100644 plugins/CustomJsTracker/lang/es.json create mode 100644 plugins/CustomJsTracker/lang/fi.json create mode 100644 plugins/CustomJsTracker/lang/fr.json create mode 100644 plugins/CustomJsTracker/lang/id.json create mode 100644 plugins/CustomJsTracker/lang/it.json create mode 100644 plugins/CustomJsTracker/lang/ja.json create mode 100644 plugins/CustomJsTracker/lang/nb.json create mode 100644 plugins/CustomJsTracker/lang/nl.json create mode 100644 plugins/CustomJsTracker/lang/pl.json create mode 100644 plugins/CustomJsTracker/lang/pt-br.json create mode 100644 plugins/CustomJsTracker/lang/pt.json create mode 100644 plugins/CustomJsTracker/lang/ru.json create mode 100644 plugins/CustomJsTracker/lang/sq.json create mode 100644 plugins/CustomJsTracker/lang/sr.json create mode 100644 plugins/CustomJsTracker/lang/sv.json create mode 100644 plugins/CustomJsTracker/lang/tr.json create mode 100644 plugins/CustomJsTracker/lang/uk.json create mode 100644 plugins/CustomJsTracker/lang/zh-cn.json create mode 100644 plugins/CustomJsTracker/lang/zh-tw.json create mode 100644 plugins/CustomJsTracker/tests/Framework/Mock/PluginTrackerFilesMock.php create mode 100644 plugins/CustomJsTracker/tests/Integration/ApiTest.php create mode 100644 plugins/CustomJsTracker/tests/Integration/FileTest.php create mode 100644 plugins/CustomJsTracker/tests/Integration/PiwikJsManipulatorTest.php create mode 100644 plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php create mode 100644 plugins/CustomJsTracker/tests/Integration/TrackerUpdaterTest.php create mode 100644 plugins/CustomJsTracker/tests/System/PiwikJsContentTest.php create mode 100644 plugins/CustomJsTracker/tests/resources/MyTestTarget2.js create mode 100644 plugins/CustomJsTracker/tests/resources/test.js create mode 100644 plugins/CustomJsTracker/tests/resources/testpiwik.js create mode 100644 plugins/CustomJsTracker/tests/resources/tracker.js create mode 100644 plugins/CustomJsTracker/tests/resources/tracker.min.js (limited to 'plugins/CustomJsTracker') diff --git a/plugins/CustomJsTracker/.gitignore b/plugins/CustomJsTracker/.gitignore new file mode 100644 index 0000000000..8f30992923 --- /dev/null +++ b/plugins/CustomJsTracker/.gitignore @@ -0,0 +1,2 @@ +tests/System/processed/*xml +tests/resources/MyNotExisIngFilessss.js diff --git a/plugins/CustomJsTracker/API.php b/plugins/CustomJsTracker/API.php new file mode 100644 index 0000000000..c8349efe2e --- /dev/null +++ b/plugins/CustomJsTracker/API.php @@ -0,0 +1,42 @@ +checkWillSucceed(); + return true; + } catch (AccessDeniedException $e) { + return false; + } catch (\Exception $e) { + return false; + } + } + +} diff --git a/plugins/CustomJsTracker/Commands/UpdateTracker.php b/plugins/CustomJsTracker/Commands/UpdateTracker.php new file mode 100644 index 0000000000..bddd99136a --- /dev/null +++ b/plugins/CustomJsTracker/Commands/UpdateTracker.php @@ -0,0 +1,66 @@ +setName('custom-piwik-js:update'); + $this->setAliases(array('custom-matomo-js:update')); + $this->addOption('source-file', null, InputOption::VALUE_REQUIRED, 'Absolute path to source PiwikJS file.', $this->getPathOriginalPiwikJs()); + $this->addOption('target-file', null, InputOption::VALUE_REQUIRED, 'Absolute path to target file. Useful if your /matomo.js is not writable and you want to replace the file manually', PIWIK_DOCUMENT_ROOT . TrackerUpdater::TARGET_MATOMO_JS); + $this->addOption('ignore-minified', null, InputOption::VALUE_NONE, 'Ignore minified tracker files, useful during development so the original source file can be debugged'); + $this->setDescription('Update the Javascript Tracker with plugin tracker additions'); + } + + private function getPathOriginalPiwikJs() + { + return PIWIK_DOCUMENT_ROOT . TrackerUpdater::ORIGINAL_PIWIK_JS; + } + + protected function execute(InputInterface $input, OutputInterface $output) + { + $sourceFile = $input->getOption('source-file'); + $targetFile = $input->getOption('target-file'); + $ignoreMinified = (bool)$input->getOption('ignore-minified'); + + $this->updateTracker($sourceFile, $targetFile, $ignoreMinified); + + $output->writeln('The Javascript Tracker has been updated'); + } + + public function updateTracker($sourceFile, $targetFile, $ignoreMinified) + { + $pluginTrackerFiles = StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackingCode\PluginTrackerFiles'); + + if ($ignoreMinified) { + if (empty($sourceFile) || $sourceFile === $this->getPathOriginalPiwikJs()) { + // no custom source file was requested + $sourceFile = PIWIK_DOCUMENT_ROOT . TrackerUpdater::DEVELOPMENT_PIWIK_JS; + } + $pluginTrackerFiles->ignoreMinified(); + } + + $updater = StaticContainer::getContainer()->make('Piwik\Plugins\CustomJsTracker\TrackerUpdater', array( + 'fromFile' => $sourceFile, 'toFile' => $targetFile + )); + $updater->setTrackerFiles($pluginTrackerFiles); + $updater->checkWillSucceed(); + $updater->update(); + } +} diff --git a/plugins/CustomJsTracker/CustomJsTracker.php b/plugins/CustomJsTracker/CustomJsTracker.php new file mode 100644 index 0000000000..ebf63933fa --- /dev/null +++ b/plugins/CustomJsTracker/CustomJsTracker.php @@ -0,0 +1,41 @@ + 'updateTracker', + 'PluginManager.pluginActivated' => 'updateTracker', + 'PluginManager.pluginDeactivated' => 'updateTracker', + 'PluginManager.pluginInstalled' => 'updateTracker', + 'PluginManager.pluginUninstalled' => 'updateTracker', + 'Updater.componentUpdated' => 'updateTracker', + 'Controller.CoreHome.checkForUpdates.end' => 'updateTracker' + ); + } + + public function updateTracker() + { + try { + if (Plugin\Manager::getInstance()->isPluginActivated('CustomJsTracker')) { + $trackerUpdater = StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackerUpdater'); + $trackerUpdater->update(); + } + } catch (\Exception $e) { + Log::error('There was an error while updating the javascript tracker: ' . $e->getMessage()); + } + } +} diff --git a/plugins/CustomJsTracker/Diagnostic/TrackerJsCheck.php b/plugins/CustomJsTracker/Diagnostic/TrackerJsCheck.php new file mode 100644 index 0000000000..5def5fa717 --- /dev/null +++ b/plugins/CustomJsTracker/Diagnostic/TrackerJsCheck.php @@ -0,0 +1,82 @@ +translator = $translator; + } + + public function execute() + { + // for users that installed matomo 3.7+ we only check for matomo.js being writable... for all other users we + // check both piwik.js and matomo.js as they can use both + $filesToCheck = array('matomo.js'); + + $jsCodeGenerator = new TrackerCodeGenerator(); + if (SettingsPiwik::isMatomoInstalled() && $jsCodeGenerator->shouldPreferPiwikEndpoint()) { + // if matomo is not installed yet, we definitely prefer matomo.js... check for isMatomoInstalled is needed + // cause otherwise it would perform a db query before matomo DB is configured + $filesToCheck[] = 'piwik.js'; + } + + $notWritableFiles = array(); + foreach ($filesToCheck as $fileToCheck) { + $file = new File(PIWIK_DOCUMENT_ROOT . '/' . $fileToCheck); + + if (!$file->hasWriteAccess()) { + $notWritableFiles[] = $fileToCheck; + } + } + + $label = $this->translator->translate('CustomJsTracker_DiagnosticPiwikJsWritable', $this->makeFilesTitles($filesToCheck)); + + if (empty($notWritableFiles)) { + return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_OK, '')); + } + + $comment = $this->translator->translate('CustomJsTracker_DiagnosticPiwikJsNotWritable', $this->makeFilesTitles($notWritableFiles)); + + if (!SettingsServer::isWindows()) { + $command = ''; + foreach ($notWritableFiles as $notWritableFile) { + $realpath = Filesystem::realpath(PIWIK_INCLUDE_PATH . '/' . $notWritableFile); + $command .= "
chmod +w $realpath
chown ". Filechecks::getUserAndGroup() ." " . $realpath . "

"; + } + $comment .= $this->translator->translate('CustomJsTracker_DiagnosticPiwikJsMakeWritable', array($this->makeFilesTitles($notWritableFiles), $command)); + } + + return array(DiagnosticResult::singleResult($label, DiagnosticResult::STATUS_WARNING, $comment)); + } + + private function makeFilesTitles($files) + { + return '"/'. implode('" & "/', $files) .'"'; + } + +} diff --git a/plugins/CustomJsTracker/Exception/AccessDeniedException.php b/plugins/CustomJsTracker/Exception/AccessDeniedException.php new file mode 100644 index 0000000000..7cfd6a550e --- /dev/null +++ b/plugins/CustomJsTracker/Exception/AccessDeniedException.php @@ -0,0 +1,15 @@ +file = $file; + } + + public function setFile($file) + { + return new static($file); + } + + public function checkReadable() + { + if (!$this->hasReadAccess()) { + throw new AccessDeniedException(sprintf('The file %s is not readable', $this->file)); + } + } + + public function checkWritable() + { + if (!$this->hasWriteAccess()) { + throw new AccessDeniedException(sprintf('The file %s is not writable', $this->file)); + } + } + + public function isFileContentSame($content) + { + // we determine if file content is the same in here in case a different "file" implementation needs to check + // whether multiple files are up to date + return $this->getContent() === $content; + } + + public function save($content) + { + if (false === file_put_contents($this->file, $content, LOCK_EX)) { + throw new AccessDeniedException(sprintf("Could not write to %s", $this->file)); + } + // we need to return an array of files in case some other "File" implementation actually updates multiple files + // eg one file per trusted host + return [$this->getPath()]; + } + + public function getContent() + { + if (!$this->hasReadAccess()) { + return null; + } + + return file_get_contents($this->file); + } + + public function getPath() + { + return $this->file; + } + + public function getName() + { + return basename($this->file); + } + + /** + * @return bool + */ + public function hasWriteAccess() + { + if (file_exists($this->file) && !is_writable($this->file)) { + return false; + } + return is_writable(dirname($this->file)) || is_writable($this->file); + } + + /** + * @return bool + */ + public function hasReadAccess() + { + return file_exists($this->file) && is_readable($this->file); + } + + +} diff --git a/plugins/CustomJsTracker/Tasks.php b/plugins/CustomJsTracker/Tasks.php new file mode 100644 index 0000000000..24427a6d43 --- /dev/null +++ b/plugins/CustomJsTracker/Tasks.php @@ -0,0 +1,25 @@ +hourly('updateTracker'); + } + + public function updateTracker() + { + $updater = StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackerUpdater'); + $updater->update(); + } +} diff --git a/plugins/CustomJsTracker/TrackerUpdater.php b/plugins/CustomJsTracker/TrackerUpdater.php new file mode 100644 index 0000000000..c301862b90 --- /dev/null +++ b/plugins/CustomJsTracker/TrackerUpdater.php @@ -0,0 +1,165 @@ +update(); + */ +class TrackerUpdater +{ + const DEVELOPMENT_PIWIK_JS = '/js/piwik.js'; + const ORIGINAL_PIWIK_JS = '/js/piwik.min.js'; + const TARGET_MATOMO_JS = '/matomo.js'; + + /** + * @var File + */ + private $fromFile; + + /** + * @var File + */ + private $toFile; + + private $trackerFiles = array(); + + /** + * @param string|null $fromFile If null then the minified JS tracker file in /js fill be used + * @param string|null $toFile If null then the minified JS tracker will be updated. + */ + public function __construct($fromFile = null, $toFile = null) + { + if (!isset($fromFile)) { + $fromFile = PIWIK_DOCUMENT_ROOT . self::ORIGINAL_PIWIK_JS; + } + + if (!isset($toFile)) { + $toFile = PIWIK_DOCUMENT_ROOT . self::TARGET_MATOMO_JS; + } + + $this->setFromFile($fromFile); + $this->setToFile($toFile); + $this->trackerFiles = StaticContainer::get('Piwik\Plugins\CustomJsTracker\TrackingCode\PluginTrackerFiles'); + } + + public function setFromFile($fromFile) + { + if (is_string($fromFile)) { + $fromFile = new File($fromFile); + } + $this->fromFile = $fromFile; + } + + public function getFromFile() + { + return $this->fromFile; + } + + public function setToFile($toFile) + { + if (is_string($toFile)) { + $toFile = new File($toFile); + } + $this->toFile = $toFile; + } + + public function getToFile() + { + return $this->toFile; + } + + public function setTrackerFiles(PluginTrackerFiles $trackerFiles) + { + $this->trackerFiles = $trackerFiles; + } + + /** + * Checks whether the Piwik JavaScript tracker file "piwik.js" is writable. + * @throws \Exception In case the piwik.js file is not writable. + * + * @api + */ + public function checkWillSucceed() + { + $this->fromFile->checkReadable(); + $this->toFile->checkWritable(); + } + + public function getCurrentTrackerFileContent() + { + return $this->toFile->getContent(); + } + + public function getUpdatedTrackerFileContent() + { + $trackingCode = new PiwikJsManipulator($this->fromFile->getContent(), $this->trackerFiles); + $newContent = $trackingCode->manipulateContent(); + + return $newContent; + } + + /** + * Updates / re-generates the Piwik JavaScript tracker "piwik.js". + * + * It may not be possible to update the "piwik.js" tracker file if the file is not writable. It won't throw + * an exception in such a case and instead just to nothing. To check if the update would succeed, call + * {@link checkWillSucceed()}. + * + * @api + */ + public function update() + { + if (!$this->toFile->hasWriteAccess() || !$this->fromFile->hasReadAccess()) { + return; + } + + $newContent = $this->getUpdatedTrackerFileContent(); + + if (!$this->toFile->isFileContentSame($newContent)) { + $savedFiles = $this->toFile->save($newContent); + foreach ($savedFiles as $savedFile) { + + /** + * Triggered after the tracker JavaScript content (the content of the piwik.js file) is changed. + * + * @param string $absolutePath The path to the new piwik.js file. + */ + Piwik::postEvent('CustomJsTracker.trackerJsChanged', [$savedFile]); + } + + } + + // we need to make sure to sync matomo.js / piwik.js + $this->updateAlternative('piwik.js', 'matomo.js', $newContent); + $this->updateAlternative('matomo.js', 'piwik.js', $newContent); + } + + private function updateAlternative($fromFile, $toFile, $newContent) + { + if (Common::stringEndsWith($this->toFile->getName(), $fromFile)) { + $alternativeFilename = dirname($this->toFile->getPath()) . DIRECTORY_SEPARATOR . $toFile; + $file = $this->toFile->setFile($alternativeFilename); + if ($file->hasWriteAccess() && !$file->isFileContentSame($newContent)) { + $savedFiles = $file->save($newContent); + foreach ($savedFiles as $savedFile) { + Piwik::postEvent('CustomJsTracker.trackerJsChanged', [$savedFile]); + } + } + } + } +} diff --git a/plugins/CustomJsTracker/TrackingCode/JsTestPluginTrackerFiles.php b/plugins/CustomJsTracker/TrackingCode/JsTestPluginTrackerFiles.php new file mode 100644 index 0000000000..7bf8062a8b --- /dev/null +++ b/plugins/CustomJsTracker/TrackingCode/JsTestPluginTrackerFiles.php @@ -0,0 +1,27 @@ +ignoreMinified = true; + } + + protected function isPluginActivated($pluginName) + { + return true; + } + +} diff --git a/plugins/CustomJsTracker/TrackingCode/PiwikJsManipulator.php b/plugins/CustomJsTracker/TrackingCode/PiwikJsManipulator.php new file mode 100644 index 0000000000..0fe821c4e6 --- /dev/null +++ b/plugins/CustomJsTracker/TrackingCode/PiwikJsManipulator.php @@ -0,0 +1,77 @@ +content = $content; + $this->pluginTrackerFiles = $pluginTrackerFiles; + } + + public function manipulateContent() + { + $files = $this->pluginTrackerFiles->find(); + + foreach ($files as $file) { + $trackerExtension = $this->getSignatureWithContent($file->getName(), $file->getContent()); + + // for some reasons it is /*!!! in piwik.js minified and /*!! in js/piwik.js unminified + $this->content = str_replace(array(self::HOOK, '/*!! pluginTrackerHook */'), self::HOOK . $trackerExtension, $this->content); + } + + $content = $this->content; + + /** + * Triggered after the Matomo JavaScript tracker has been generated and shortly before the tracker file + * is written to disk. You can listen to this event to for example automatically append some code to the JS + * tracker file. + * + * **Example** + * + * function onManipulateJsTracker (&$content) { + * $content .= "\nPiwik.DOM.onLoad(function () { console.log('loaded'); });"; + * } + * + * @param string $content the generated JavaScript tracker code + */ + Piwik::postEvent('CustomMatomoJs.manipulateJsTracker', array(&$content)); + $this->content = $content; + + return $this->content; + } + + /** + * @param string $name + * @param string $content + * @return string + */ + private function getSignatureWithContent($name, $content) + { + return sprintf( + "\n\n/* GENERATED: %s */\n%s\n/* END GENERATED: %s */\n", + $name, + $content, + $name + ); + } + +} diff --git a/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php b/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php new file mode 100644 index 0000000000..e062a73516 --- /dev/null +++ b/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php @@ -0,0 +1,110 @@ +dir = PIWIK_DOCUMENT_ROOT . '/plugins/'; + $this->pluginManager = Plugin\Manager::getInstance(); + } + + public function ignoreMinified() + { + $this->ignoreMinified = true; + } + + /** + * @return File[] + */ + public function find() + { + $jsFiles = array(); + + if (!$this->ignoreMinified) { + $trackerFiles = \_glob($this->dir . '*/' . self::MIN_TRACKER_FILE); + + foreach ($trackerFiles as $trackerFile) { + $plugin = $this->getPluginNameFromFile($trackerFile); + if ($this->isPluginActivated($plugin)) { + $jsFiles[$plugin] = new File($trackerFile); + } + } + } + + $trackerFiles = \_glob($this->dir . '*/' . self::TRACKER_FILE); + + foreach ($trackerFiles as $trackerFile) { + $plugin = $this->getPluginNameFromFile($trackerFile); + if (!isset($jsFiles[$plugin])) { + if ($this->isPluginActivated($plugin)) { + $jsFiles[$plugin] = new File($trackerFile); + } + } + } + + foreach ($jsFiles as $plugin => $file) { + if (!$this->shouldIncludeFile($plugin)) { + unset($jsFiles[$plugin]); + } + } + + return $jsFiles; + } + + protected function shouldIncludeFile($pluginName) + { + $shouldAddFile = true; + + /** + * Detect if a custom tracker file should be added to the piwik.js tracker or not. + * + * This is useful for example if a plugin only wants to add its tracker file when the plugin is configured. + * + * @param bool &$shouldAddFile Decides whether the tracker file belonging to the given plugin should be added or not. + * @param string $pluginName The name of the plugin this file belongs to + */ + Piwik::postEvent('CustomJsTracker.shouldAddTrackerFile', array(&$shouldAddFile, $pluginName)); + + return $shouldAddFile; + } + + protected function isPluginActivated($pluginName) + { + return $this->pluginManager->isPluginActivated($pluginName); + } + + protected function getPluginNameFromFile($file) + { + $file = str_replace(array($this->dir, self::TRACKER_FILE, self::MIN_TRACKER_FILE), '', $file); + return trim($file, '/'); + } +} diff --git a/plugins/CustomJsTracker/config/config.php b/plugins/CustomJsTracker/config/config.php new file mode 100644 index 0000000000..88d0d6417a --- /dev/null +++ b/plugins/CustomJsTracker/config/config.php @@ -0,0 +1,7 @@ + DI\add(array( + DI\get('Piwik\Plugins\CustomJsTracker\Diagnostic\TrackerJsCheck'), + )), +); diff --git a/plugins/CustomJsTracker/config/tracker.php b/plugins/CustomJsTracker/config/tracker.php new file mode 100644 index 0000000000..ca2affec34 --- /dev/null +++ b/plugins/CustomJsTracker/config/tracker.php @@ -0,0 +1,2 @@ +files = $files; + } + + public function find() + { + $files = array(); + foreach ($this->files as $file) { + $files[] = new File(PIWIK_DOCUMENT_ROOT . $file); + } + return $files; + } + + +} diff --git a/plugins/CustomJsTracker/tests/Integration/ApiTest.php b/plugins/CustomJsTracker/tests/Integration/ApiTest.php new file mode 100644 index 0000000000..b8ffa36602 --- /dev/null +++ b/plugins/CustomJsTracker/tests/Integration/ApiTest.php @@ -0,0 +1,84 @@ +api = API::getInstance(); + } + + /** + * @expectedException \Piwik\NoAccessException + * @expectedExceptionMessage checkUserHasSomeAdminAccess + */ + public function test_doesIncludePluginTrackersAutomatically_failsIfNotEnoughPermission() + { + $this->setUser(); + $this->api->doesIncludePluginTrackersAutomatically(); + } + + /** + * @expectedException \Piwik\NoAccessException + * @expectedExceptionMessage checkUserHasSomeAdminAccess + */ + public function test_doesIncludePluginTrackersAutomatically_failsIfNotEnoughPermissionAnonymous() + { + $this->setAnonymousUser(); + $this->api->doesIncludePluginTrackersAutomatically(); + } + + public function test_doesIncludePluginTrackersAutomatically_returnsValueWhenEnoughPermission() + { + $this->assertTrue($this->api->doesIncludePluginTrackersAutomatically()); + } + + protected function setUser() + { + FakeAccess::clearAccess(false); + FakeAccess::$identity = 'testUsername'; + FakeAccess::$idSitesView = array(1); + FakeAccess::$idSitesAdmin = array(); + } + + protected function setAnonymousUser() + { + FakeAccess::clearAccess(); + FakeAccess::$identity = 'anonymous'; + } + + public function provideContainerConfig() + { + return array( + 'Piwik\Access' => new FakeAccess() + ); + } + +} diff --git a/plugins/CustomJsTracker/tests/Integration/FileTest.php b/plugins/CustomJsTracker/tests/Integration/FileTest.php new file mode 100644 index 0000000000..1457de0336 --- /dev/null +++ b/plugins/CustomJsTracker/tests/Integration/FileTest.php @@ -0,0 +1,210 @@ +dir = PIWIK_DOCUMENT_ROOT . '/plugins/CustomJsTracker/tests/resources/'; + + // make directory not writable + $nonWritableDir = dirname($this->dir . self::NOT_EXISTING_FILE_IN_NON_WRITABLE_DIRECTORY); + @chmod($nonWritableDir, 0444); + if(is_writable($nonWritableDir)) { + throw new \Exception("The directory $nonWritableDir should have been made non writable by this test, but it didn't work"); + } + } + + public function tearDown() + { + // restore permissions changed by makeNotWritableFile() + chmod($this->dir, 0777); + + if (file_exists($this->dir . self::NOT_EXISTING_FILE_IN_WRITABLE_DIRECTORY)) { + unlink($this->dir . self::NOT_EXISTING_FILE_IN_WRITABLE_DIRECTORY); + } + parent::tearDown(); + } + + private function makeFile($fileName = 'test.js') + { + return new File($this->dir . $fileName); + } + + private function makeNotWritableFile() + { + $path = $this->dir . 'file-made-non-writable.js'; + if(file_exists($path)) { + chmod($path, 0777); + } + $file = new File($path); + $file->save('will be saved OK, and then we make it non writable.'); + + if (!chmod($path, 0444)) { + throw new \Exception("chmod on the file didn't work"); + } + if (!chmod(dirname($path), 0755)) { + throw new \Exception("chmod on the directory didn't work"); + } + $this->assertTrue(is_writable(dirname($path))); + $this->assertFalse(is_writable($path)); + $this->assertTrue(file_exists($path)); + return $file; + } + + private function makeNotReadableFile() + { + return $this->makeNotReadableFile_inWritableDirectory(); + } + + private function makeNotReadableFile_inNonWritableDirectory() + { + return $this->makeFile(self::NOT_EXISTING_FILE_IN_NON_WRITABLE_DIRECTORY); + } + + private function makeNotReadableFile_inWritableDirectory() + { + return $this->makeFile(self::NOT_EXISTING_FILE_IN_WRITABLE_DIRECTORY); + } + + public function test_getName() + { + $this->assertSame('test.js', $this->makeFile()->getName()); + $this->assertSame('notExisTinGFile.js', $this->makeNotReadableFile()->getName()); + } + + public function test_setFile_createsNewObjectLeavesOldUnchanged() + { + $file = $this->makeFile(); + $file2 = $file->setFile('foo/bar.png'); + $this->assertSame('test.js', $file->getName()); + $this->assertSame('bar.png', $file2->getName()); + } + + public function test_setFile_returnsObjectOfSameType() + { + $file = new CustomTestFile('foo/baz.png'); + $file2 = $file->setFile('foo/bar.png'); + $this->assertTrue($file2 instanceof CustomTestFile); + } + + public function test_getPath() + { + $this->assertSame($this->dir . 'notExisTinGFile.js', $this->makeNotReadableFile()->getPath()); + } + + public function test_hasReadAccess() + { + $this->assertTrue($this->makeFile()->hasReadAccess()); + $this->assertFalse($this->makeNotReadableFile()->hasReadAccess()); + } + + public function test_hasWriteAccess() + { + $this->assertTrue($this->makeFile()->hasWriteAccess()); + $this->assertTrue($this->makeNotReadableFile_inWritableDirectory()->hasWriteAccess()); + $this->assertFalse($this->makeNotReadableFile_inNonWritableDirectory()->hasWriteAccess()); + } + + public function test_hasWriteAccess_whenFileExistAndIsNotWritable() + { + $this->assertFalse($this->makeNotWritableFile()->hasWriteAccess()); + } + + public function test_checkReadable_shouldNotThrowException_IfIsReadable() + { + $this->makeFile()->checkReadable(); + $this->assertTrue(true); + } + + public function test_checkWritable_shouldNotThrowException_IfIsWritable() + { + $this->makeFile()->checkWritable(); + $this->assertTrue(true); + } + + /** + * @expectedException \Piwik\Plugins\CustomJsTracker\Exception\AccessDeniedException + * @expectedExceptionMessage not readable + */ + public function test_checkReadable_shouldThrowException_IfNotIsReadable() + { + $this->makeNotReadableFile()->checkReadable(); + } + + /** + * @expectedException \Piwik\Plugins\CustomJsTracker\Exception\AccessDeniedException + * @expectedExceptionMessage not writable + */ + public function test_checkWritable_shouldThrowException_IfNotIsWritable() + { + $this->makeNotReadableFile_inNonWritableDirectory()->checkWritable(); + } + + public function test_checkWritable_shouldNotThrowException_IfDirectoryIsWritable() + { + $this->makeNotReadableFile_inWritableDirectory()->checkWritable(); + } + + public function test_getContent() + { + $this->assertSame("// Hello world\nvar fooBar = 'test';", $this->makeFile()->getContent()); + } + + public function test_isFileContentSame() + { + $this->assertTrue($this->makeFile()->isFileContentSame("// Hello world\nvar fooBar = 'test';")); + $this->assertFalse($this->makeFile()->isFileContentSame("// Hello world\nvar foBar = 'test';")); + $this->assertFalse($this->makeFile()->isFileContentSame("// Hello world\nvar foBar = 'test'")); + $this->assertFalse($this->makeFile()->isFileContentSame("Hello world\nvar foBar = 'test'")); + } + + public function test_getContent_returnsNull_IfFileIsNotReadableOrNotExists() + { + $this->assertNull($this->makeNotReadableFile()->getContent()); + } + + public function test_save() + { + $notExistingFile = $this->makeNotReadableFile_inWritableDirectory(); + $this->assertFalse($notExistingFile->hasReadAccess()); + $this->assertTrue($notExistingFile->hasWriteAccess()); + + $updatedFile = $notExistingFile->save('myTestContent'); + + $this->assertEquals([$this->dir . 'notExisTinGFile.js'], $updatedFile); + $this->assertEquals('myTestContent', $notExistingFile->getContent()); + $this->assertTrue($notExistingFile->hasReadAccess()); + $this->assertTrue($notExistingFile->hasWriteAccess()); + } + +} diff --git a/plugins/CustomJsTracker/tests/Integration/PiwikJsManipulatorTest.php b/plugins/CustomJsTracker/tests/Integration/PiwikJsManipulatorTest.php new file mode 100644 index 0000000000..3decbd21f7 --- /dev/null +++ b/plugins/CustomJsTracker/tests/Integration/PiwikJsManipulatorTest.php @@ -0,0 +1,73 @@ +makeManipulator(array( + '/plugins/CustomJsTracker/tests/resources/tracker.js', + '/plugins/CustomJsTracker/tests/resources/tracker.min.js', + )); + + $updatedContent = $manipulator->manipulateContent(); + + $this->assertSame('var Piwik.js = "mytest"; +/*!!! pluginTrackerHook */ + +/* GENERATED: tracker.min.js */ +/* my license header */ +var mySecondCustomTracker = \'test\'; +/* END GENERATED: tracker.min.js */ + + +/* GENERATED: tracker.js */ +/** my license header*/ +var myCustomTracker = \'test\'; + +var fooBar = \'baz\'; +/* END GENERATED: tracker.js */ + + +var myArray = []; +', $updatedContent); + } + + public function test_manipulateContent_shouldNotAddCodeOfTrackerPlugins_IfThereAreNoTrackerFiles() + { + $manipulator = $this->makeManipulator(array()); + + $updatedContent = $manipulator->manipulateContent(); + + $this->assertSame($this->content, $updatedContent); + } + + private function makeManipulator($files) + { + return new PiwikJsManipulator($this->content, new PluginTrackerFilesMock($files)); + } + +} diff --git a/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php b/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php new file mode 100644 index 0000000000..b063fbab28 --- /dev/null +++ b/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php @@ -0,0 +1,143 @@ +dir = PIWIK_DOCUMENT_ROOT . '/plugins/CustomJsTracker/tests/'; + + $this->pluginNamesForFile = array( + 'tracker.js' => $pluginNameForRegularTrackerFile, + 'tracker.min.js' => $pluginNameForMinifiedTracker + ); + } + + protected function getPluginNameFromFile($file) + { + $fileName = basename($file); + return $this->pluginNamesForFile[$fileName]; + } +} + +class CustomPluginTrackerFiles2 extends PluginTrackerFiles { + + public function getPluginNameFromFile($file) + { + return parent::getPluginNameFromFile($file); + } +} + +/** + * @group CustomJsTracker + * @group PluginTrackerFilesTest + * @group PluginTrackerFiles + * @group Plugins + */ +class PluginTrackerFilesTest extends IntegrationTestCase +{ + public function test_find_ifAPluginDefinesAMinifiedAndARegularTrackerItShouldPreferTheMinifiedVersion() + { + $trackerFiles = new CustomPluginTrackerFiles(); + $foundFiles = $trackerFiles->find(); + + $this->assertCount(1, $foundFiles); + $this->assertTrue(isset($foundFiles['CustomJsTracker'])); + $this->assertEquals('tracker.min.js', $foundFiles['CustomJsTracker']->getName()); + } + + public function test_find_shouldIgnoreMinifiedVersion_IfRequested() + { + $trackerFiles = new CustomPluginTrackerFiles(); + $trackerFiles->ignoreMinified(); + $foundFiles = $trackerFiles->find(); + + $this->assertCount(1, $foundFiles); + $this->assertTrue(isset($foundFiles['CustomJsTracker'])); + $this->assertEquals('tracker.js', $foundFiles['CustomJsTracker']->getName()); + } + + public function test_find_ifMultiplePluginsImplementATracker_ShouldReturnEachOfThem() + { + $trackerFiles = new CustomPluginTrackerFiles('CustomJsTracker', 'Goals'); + $foundFiles = $trackerFiles->find(); + + $this->assertCount(2, $foundFiles); + $this->assertTrue(isset($foundFiles['CustomJsTracker'])); + $this->assertTrue(isset($foundFiles['Goals'])); + $this->assertEquals('tracker.js', $foundFiles['CustomJsTracker']->getName()); + $this->assertEquals('tracker.min.js', $foundFiles['Goals']->getName()); + } + + public function test_find_EventsCanIgnoreFiles() + { + $trackerFiles = new CustomPluginTrackerFiles('CustomJsTracker', 'Goals'); + $foundFiles = $trackerFiles->find(); + $this->assertCount(2, $foundFiles); + + Piwik::addAction('CustomJsTracker.shouldAddTrackerFile', function (&$shouldAdd, $pluginName) { + if ($pluginName === 'Goals') { + $shouldAdd = false; + } + }); + + $foundFiles = $trackerFiles->find(); + $this->assertCount(1, $foundFiles); + $this->assertTrue(isset($foundFiles['CustomJsTracker'])); + $this->assertFalse(isset($foundFiles['Goals'])); + } + + public function test_find_shouldNotReturnATrackerFile_IfPluginIsNotActivatedOrLoaded() + { + $trackerFiles = new CustomPluginTrackerFiles('MyNotExistingPlugin', 'Goals'); + $foundFiles = $trackerFiles->find(); + + $this->assertCount(1, $foundFiles); + $this->assertTrue(isset($foundFiles['Goals'])); + $this->assertEquals('tracker.min.js', $foundFiles['Goals']->getName()); + + $trackerFiles = new CustomPluginTrackerFiles('Goals', 'MyNotExistingPlugin'); + $foundFiles = $trackerFiles->find(); + + $this->assertCount(1, $foundFiles); + $this->assertTrue(isset($foundFiles['Goals'])); + $this->assertEquals('tracker.js', $foundFiles['Goals']->getName()); + } + + public function test_find_shouldNotReturnFileIfNoPluginActivated() + { + $trackerFiles = new CustomPluginTrackerFiles('MyNotExistingPlugin', 'MyNotExistingPlugin2'); + $foundFiles = $trackerFiles->find(); + + $this->assertSame(array(), $foundFiles); + } + + public function test_getPluginNameFromFile_shouldDetectPluginName() + { + $trackerFiles = new CustomPluginTrackerFiles2(); + $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins/MyFooBarPlugin/tracker.js'); + $this->assertSame('MyFooBarPlugin', $pluginName); + + $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins//MyFooBarPlugin//tracker.js'); + $this->assertSame('MyFooBarPlugin', $pluginName); + + $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins//MyFooBarPlugin//tracker.min.js'); + $this->assertSame('MyFooBarPlugin', $pluginName); + } + +} diff --git a/plugins/CustomJsTracker/tests/Integration/TrackerUpdaterTest.php b/plugins/CustomJsTracker/tests/Integration/TrackerUpdaterTest.php new file mode 100644 index 0000000000..0c0130e5b6 --- /dev/null +++ b/plugins/CustomJsTracker/tests/Integration/TrackerUpdaterTest.php @@ -0,0 +1,246 @@ +dir = PIWIK_DOCUMENT_ROOT . '/plugins/CustomJsTracker/tests/resources/'; + $this->trackerJsChangedEventPath = null; + + $this->cleanUp(); + } + + public function tearDown() + { + parent::tearDown(); + + $this->cleanUp(); + } + + private function cleanUp() + { + $target = $this->dir . 'MyTestTarget.js'; + if (file_exists($target)) { + unlink($target); + } + + $nonExistentFile = $this->dir . 'MyNotExisIngFilessss.js'; + if (file_exists($nonExistentFile)) { + unlink($nonExistentFile); + } + } + + private function makeUpdater($from = null, $to = null) + { + return new TrackerUpdater($from, $to); + } + + public function test_construct_setsDefaults() + { + $updater = $this->makeUpdater(); + $fromFile = $updater->getFromFile(); + $toFile = $updater->getToFile(); + $this->assertTrue($fromFile instanceof File); + $this->assertTrue($toFile instanceof File); + + $this->assertSame(basename(TrackerUpdater::ORIGINAL_PIWIK_JS), $fromFile->getName()); + $this->assertSame(basename(TrackerUpdater::TARGET_MATOMO_JS), $toFile->getName()); + } + + public function test_setFormFile_getFromFile() + { + $updater = $this->makeUpdater(); + $testFile = new File('foobar'); + $updater->setFromFile($testFile); + + $this->assertSame($testFile, $updater->getFromFile()); + } + + public function test_setFormFile_CanBeString() + { + $updater = $this->makeUpdater(); + $updater->setFromFile('foobar'); + + $this->assertSame('foobar', $updater->getFromFile()->getName()); + } + + public function test_setToFile_getToFile() + { + $updater = $this->makeUpdater(); + $testFile = new File('foobar'); + $updater->setToFile($testFile); + + $this->assertSame($testFile, $updater->getToFile()); + } + + public function test_setToFile_CanBeString() + { + $updater = $this->makeUpdater(); + $updater->setToFile('foobar'); + + $this->assertSame('foobar', $updater->getToFile()->getName()); + } + + public function test_checkWillSucceed_shouldNotThrowExceptionIfPiwikJsTargetIsWritable() + { + $updater = $this->makeUpdater(); + $updater->checkWillSucceed(); + + $this->assertTrue(true); + } + + /** + * @expectedException \Piwik\Plugins\CustomJsTracker\Exception\AccessDeniedException + * @expectedExceptionMessage not writable + */ + public function test_checkWillSucceed_shouldNotThrowExceptionIfTargetIsNotWritable() + { + $updater = $this->makeUpdater(null, $this->dir . 'not-writable/MyNotExisIngFilessss.js'); + $updater->checkWillSucceed(); + } + + public function test_checkWillSucceed_shouldNotThrowExceptionIfTargetIsWritable() + { + $updater = $this->makeUpdater(null, $this->dir . 'MyNotExisIngFilessss.js'); + $updater->checkWillSucceed(); + } + + public function test_getCurrentTrackerFileContent() + { + $targetFile = $this->dir . 'testpiwik.js'; + + $updater = $this->makeUpdater(null, $targetFile); + $content = $updater->getCurrentTrackerFileContent(); + + $this->assertSame(file_get_contents($targetFile), $content); + } + + public function test_getUpdatedTrackerFileContent_returnsGeneratedPiwikJsWithMergedTrackerFiles_WhenTheyExist() + { + $source = $this->dir . 'testpiwik.js'; + $target = $this->dir . 'MyTestTarget.js'; + + $updater = $this->makeUpdater($source, $target); + $updater->setTrackerFiles(new PluginTrackerFilesMock(array( + $this->dir . 'tracker.js', $this->dir . 'tracker.min.js' + ))); + $content = $updater->getUpdatedTrackerFileContent(); + + $this->assertSame('/** MyHeader*/ +var PiwikJs = "mytest"; + +/*!!! pluginTrackerHook */ + +/* GENERATED: tracker.min.js */ + +/* END GENERATED: tracker.min.js */ + + +/* GENERATED: tracker.js */ + +/* END GENERATED: tracker.js */ + + +var myArray = []; +', $content); + } + + public function test_getUpdatedTrackerFileContent_returnsSourceFile_IfNoTrackerFilesFound() + { + $source = $this->dir . 'testpiwik.js'; + $target = $this->dir . 'MyTestTarget.js'; + + $updater = $this->makeUpdater($source, $target); + $updater->setTrackerFiles(new PluginTrackerFilesMock(array())); + $content = $updater->getUpdatedTrackerFileContent(); + + $this->assertSame(file_get_contents($source), $content); + } + + public function test_update_shouldNotThrowAnError_IfTargetFileIsNotWritable() + { + $updater = $this->makeUpdater(null, $this->dir . 'not-writable/MyNotExisIngFilessss.js'); + $updater->update(); + $this->assertTrue(true); + $this->assertNull($this->trackerJsChangedEventPath); + } + + public function test_update_shouldNotWriteToFileIfThereIsNothingToChange() + { + $source = $this->dir . 'testpiwik.js'; + $target = $this->dir . 'MyTestTarget.js'; + file_put_contents($target, file_get_contents($source)); + $updater = $this->makeUpdater($this->dir . 'testpiwik.js', $target); + $updater->setTrackerFiles(new PluginTrackerFilesMock(array())); + // mock that does not find any files . therefore there is nothing to di + $updater->update(); + + $this->assertSame(file_get_contents($source), file_get_contents($target)); + $this->assertNull($this->trackerJsChangedEventPath); + } + + public function test_update_targetFileIfPluginsDefineDifferentFiles() + { + $target = $this->dir . 'MyTestTarget.js'; + file_put_contents($target, ''); // file has to exist in order to work + + $updater = $this->makeUpdater($this->dir . 'testpiwik.js', $target); + $updater->setTrackerFiles(new PluginTrackerFilesMock(array( + $this->dir . 'tracker.js', $this->dir . 'tracker.min.js' + ))); + $updater->update(); + + $this->assertSame('/** MyHeader*/ +var PiwikJs = "mytest"; + +/*!!! pluginTrackerHook */ + +/* GENERATED: tracker.min.js */ + +/* END GENERATED: tracker.min.js */ + + +/* GENERATED: tracker.js */ + +/* END GENERATED: tracker.js */ + + +var myArray = []; +', file_get_contents($target)); + $this->assertEquals($target, $this->trackerJsChangedEventPath); + } + + public function provideContainerConfig() + { + return [ + 'observers.global' => \DI\add([ + ['CustomJsTracker.trackerJsChanged', function ($path) { + $this->trackerJsChangedEventPath = $path; + }], + ]), + ]; + } +} diff --git a/plugins/CustomJsTracker/tests/System/PiwikJsContentTest.php b/plugins/CustomJsTracker/tests/System/PiwikJsContentTest.php new file mode 100644 index 0000000000..300c312984 --- /dev/null +++ b/plugins/CustomJsTracker/tests/System/PiwikJsContentTest.php @@ -0,0 +1,39 @@ +assertSame(file_get_contents($piwikMin), file_get_contents($piwikJs)); + } + + public function test_piwikJsContainsHook() + { + $piwikMin = PIWIK_DOCUMENT_ROOT . '/js/piwik.min.js'; + $content = file_get_contents($piwikMin); + + $this->assertContains(PiwikJsManipulator::HOOK, $content); + } + +} \ No newline at end of file diff --git a/plugins/CustomJsTracker/tests/resources/MyTestTarget2.js b/plugins/CustomJsTracker/tests/resources/MyTestTarget2.js new file mode 100644 index 0000000000..258c2d3e11 --- /dev/null +++ b/plugins/CustomJsTracker/tests/resources/MyTestTarget2.js @@ -0,0 +1,16 @@ +/** MyHeader*/ +var PiwikJs = "mytest"; + +/*!!! pluginTrackerHook */ + +/* GENERATED: tracker.min.js */ + +/* END GENERATED: tracker.min.js */ + + +/* GENERATED: tracker.js */ + +/* END GENERATED: tracker.js */ + + +var myArray = []; diff --git a/plugins/CustomJsTracker/tests/resources/test.js b/plugins/CustomJsTracker/tests/resources/test.js new file mode 100644 index 0000000000..0ea6fcc24a --- /dev/null +++ b/plugins/CustomJsTracker/tests/resources/test.js @@ -0,0 +1,2 @@ +// Hello world +var fooBar = 'test'; \ No newline at end of file diff --git a/plugins/CustomJsTracker/tests/resources/testpiwik.js b/plugins/CustomJsTracker/tests/resources/testpiwik.js new file mode 100644 index 0000000000..02b60f8bcd --- /dev/null +++ b/plugins/CustomJsTracker/tests/resources/testpiwik.js @@ -0,0 +1,6 @@ +/** MyHeader*/ +var PiwikJs = "mytest"; + +/*!!! pluginTrackerHook */ + +var myArray = []; diff --git a/plugins/CustomJsTracker/tests/resources/tracker.js b/plugins/CustomJsTracker/tests/resources/tracker.js new file mode 100644 index 0000000000..ae4d228f39 --- /dev/null +++ b/plugins/CustomJsTracker/tests/resources/tracker.js @@ -0,0 +1,4 @@ +/** my license header*/ +var myCustomTracker = 'test'; + +var fooBar = 'baz'; \ No newline at end of file diff --git a/plugins/CustomJsTracker/tests/resources/tracker.min.js b/plugins/CustomJsTracker/tests/resources/tracker.min.js new file mode 100644 index 0000000000..587ee0464d --- /dev/null +++ b/plugins/CustomJsTracker/tests/resources/tracker.min.js @@ -0,0 +1,2 @@ +/* my license header */ +var mySecondCustomTracker = 'test'; \ No newline at end of file -- cgit v1.2.3