15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/profiles/profile.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/spellchecker/spellcheck_factory.h"
92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/spellchecker/spellcheck_service.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/spellcheck_common.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
15eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
17d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)using content::BrowserContext;
18d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// A corrupted BDICT data used in DeleteCorruptedBDICT. Please do not use this
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// BDICT data for other tests.
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const uint8 kCorruptedBDICT[] = {
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x42, 0x44, 0x69, 0x63, 0x02, 0x00, 0x01, 0x00,
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x20, 0x00, 0x00, 0x00, 0x3b, 0x00, 0x00, 0x00,
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x65, 0x72, 0xe0, 0xac, 0x27, 0xc7, 0xda, 0x66,
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x6d, 0x1e, 0xa6, 0x35, 0xd1, 0xf6, 0xb7, 0x35,
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x32, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x00,
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x39, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x00, 0x00,
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x0a, 0x0a, 0x41, 0x46, 0x20, 0x30, 0x00, 0x00,
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x00, 0x00, 0x00, 0xe6, 0x49, 0x00, 0x68, 0x02,
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  0x73, 0x06, 0x74, 0x0b, 0x77, 0x11, 0x79, 0x15,
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class SpellcheckServiceBrowserTest : public InProcessBrowserTest {
382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public:
392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  Profile* GetProfile() {
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return browser()->profile();
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that we can delete a corrupted BDICT file used by hunspell. We do not
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// run this test on Mac because Mac does not use hunspell by default.
462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(SpellcheckServiceBrowserTest, DeleteCorruptedBDICT) {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Write the corrupted BDICT data to create a corrupted BDICT file.
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath dict_dir;
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(PathService::Get(chrome::DIR_APP_DICTIONARIES, &dict_dir));
502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::FilePath bdict_path =
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      chrome::spellcheck_common::GetVersionedFileName("en-US", dict_dir);
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  size_t actual = base::WriteFile(bdict_path,
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      reinterpret_cast<const char*>(kCorruptedBDICT),
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      arraysize(kCorruptedBDICT));
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(arraysize(kCorruptedBDICT), actual);
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
58c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Attach an event to the SpellcheckService object so we can receive its
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // status updates.
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  base::WaitableEvent event(true, false);
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  SpellcheckService::AttachStatusEvent(&event);
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
63d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  BrowserContext * context = static_cast<BrowserContext*>(GetProfile());
64d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // Ensure that the SpellcheckService object does not already exist. Otherwise
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // the next line will not force creation of the SpellcheckService and the
67c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  // test will fail.
68d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SpellcheckService* service = static_cast<SpellcheckService*>(
69d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)      SpellcheckServiceFactory::GetInstance()->GetServiceForBrowserContext(
70d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          context,
71d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)          false));
72c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  ASSERT_EQ(NULL, service);
73c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // Getting the spellcheck_service will initialize the SpellcheckService
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // object with the corrupted BDICT file created above since the hunspell
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // dictionary is loaded in the SpellcheckService constructor right now.
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // The SpellCheckHost object will send a BDICT_CORRUPTED event.
78d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)  SpellcheckServiceFactory::GetForContext(context);
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Check the received event. Also we check if Chrome has successfully deleted
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // the corrupted dictionary. We delete the corrupted dictionary to avoid
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // leaking it when this test fails.
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RunAllPendingInMessageLoop(content::BrowserThread::FILE);
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  content::RunAllPendingInMessageLoop(content::BrowserThread::UI);
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  EXPECT_EQ(SpellcheckService::BDICT_CORRUPTED,
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)            SpellcheckService::GetStatusEvent());
877dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (base::PathExists(bdict_path)) {
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
897dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    EXPECT_TRUE(base::DeleteFile(bdict_path, true));
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
92