### Question:
FileUserRepository extends AbstractUserRepository implements FileRepository { @Override public void start() throws Throwable { clear(); FileRepository.assertNotMigrated( authFile, fileSystem, log ); ListSnapshot<User> onDiskUsers = readPersistedUsers(); if ( onDiskUsers != null ) { setUsers( onDiskUsers ); } } FileUserRepository( FileSystemAbstraction fileSystem, File file, LogProvider logProvider ); @Override void start(); @Override ListSnapshot<User> getPersistedSnapshot(); @Override void purge(); @Override void markAsMigrated();  }### Answer:
@Test public void shouldPersistUsers() throws Throwable { FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); users.create( user ); users = new FileUserRepository( fs, authFile, logProvider ); users.start(); User resultByName = users.getUserByName( user.name() ); assertThat( resultByName, equalTo( user ) ); }
@Test public void shouldRecoverIfCrashedDuringMove() throws Throwable { final IOException exception = new IOException( "simulated IO Exception on create" ); FileSystemAbstraction crashingFileSystem = new DelegatingFileSystemAbstraction( fs ) { @Override public void renameFile( File oldLocation, File newLocation, CopyOption... copyOptions ) throws IOException { if ( authFile.getName().equals( newLocation.getName() ) ) { throw exception; } super.renameFile( oldLocation, newLocation, copyOptions ); } }; FileUserRepository users = new FileUserRepository( crashingFileSystem, authFile, logProvider ); users.start(); User user = new User.Builder( "jake", LegacyCredential.INACCESSIBLE ).withRequiredPasswordChange( true ).build(); try { users.create( user ); fail( "Expected an IOException" ); } catch ( IOException e ) { assertSame( exception, e ); } assertFalse( crashingFileSystem.fileExists( authFile ) ); assertThat( crashingFileSystem.listFiles( authFile.getParentFile() ).length, equalTo( 0 ) ); }
@Test public void shouldFailOnReadingInvalidEntries() throws Throwable { AssertableLogProvider logProvider = new AssertableLogProvider(); fs.mkdir( authFile.getParentFile() ); FileRepositorySerializer.writeToFile( fs, authFile, UTF8.encode( "admin:SHA-256,A42E541F276CF17036DB7818F8B09B1C229AAD52A17F69F4029617F3A554640F,FB7E8AE08A6A7C741F678AD22217808F:\n" + "neo4j:fc4c600b43ffe4d5857b4439c35df88f:SHA-256," + "A42E541F276CF17036DB7818F8B09B1C229AAD52A17F69F4029617F3A554640F,FB7E8AE08A6A7C741F678AD22217808F:\n" ) ); FileUserRepository users = new FileUserRepository( fs, authFile, logProvider ); thrown.expect( IllegalStateException.class ); thrown.expectMessage( startsWith( "Failed to read authentication file: " ) ); try { users.start(); } catch ( IllegalStateException e ) { assertThat( users.numberOfUsers(), equalTo( 0 ) ); logProvider.assertExactly( AssertableLogProvider.inLog( FileUserRepository.class ).error( "Failed to read authentication file \"%s\" (%s)", authFile.getAbsolutePath(), "wrong number of line fields, expected 3, got 4 [line 2]" ) ); throw e; } }